generated from coulomb/repo-seed
Add CARING Kubernetes RBAC benchmark
This commit is contained in:
@@ -10,8 +10,12 @@ import yaml
|
||||
|
||||
GENERATED_NOTICE = "<!-- GENERATED by info_tech_canon; do not edit by hand. -->"
|
||||
RETRIEVAL_ARTIFACT_KINDS = {
|
||||
"access-descriptor-set",
|
||||
"benefit-analysis",
|
||||
"benchmark-findings",
|
||||
"benchmark-workspace",
|
||||
"capture-criteria",
|
||||
"caring-mapping",
|
||||
"comparison-frame",
|
||||
"comparison-report",
|
||||
"concept-catalog",
|
||||
@@ -27,6 +31,7 @@ RETRIEVAL_ARTIFACT_KINDS = {
|
||||
"mapping-expectation",
|
||||
"model",
|
||||
"model-extension",
|
||||
"native-concept-map",
|
||||
"pattern",
|
||||
"profile-alignment",
|
||||
"profile",
|
||||
@@ -869,10 +874,18 @@ def _safe_id(value: str) -> str:
|
||||
def _summary_for_artifact(artifact: Any) -> str:
|
||||
if artifact.kind == "profile-artifact":
|
||||
return f"Example artifact for the {artifact.provenance.get('profile', 'unknown')} profile: {artifact.title}."
|
||||
if artifact.kind == "access-descriptor-set":
|
||||
return f"Structured CARING access descriptor set: {artifact.title}."
|
||||
if artifact.kind == "benefit-analysis":
|
||||
return f"Consumer benefit analysis against canon surfaces: {artifact.title}."
|
||||
if artifact.kind == "benchmark-findings":
|
||||
return f"Benchmark findings, gaps, and canon pressure: {artifact.title}."
|
||||
if artifact.kind == "benchmark-workspace":
|
||||
return f"Benchmark workspace definition and review criteria: {artifact.title}."
|
||||
if artifact.kind == "capture-criteria":
|
||||
return f"Criteria for canonical entity and edge capture: {artifact.title}."
|
||||
if artifact.kind == "caring-mapping":
|
||||
return f"Native access model to CARING mapping: {artifact.title}."
|
||||
if artifact.kind == "comparison-frame":
|
||||
return f"Structured comparison questions and domains: {artifact.title}."
|
||||
if artifact.kind == "comparison-report":
|
||||
@@ -899,6 +912,8 @@ def _summary_for_artifact(artifact: Any) -> str:
|
||||
return f"Expected mappings between consumer graph capture and canon surfaces: {artifact.title}."
|
||||
if artifact.kind == "model-extension":
|
||||
return f"Candidate extension to an existing canon model: {artifact.title}."
|
||||
if artifact.kind == "native-concept-map":
|
||||
return f"Native source concept map for assimilation or benchmark work: {artifact.title}."
|
||||
if artifact.kind == "pattern":
|
||||
return f"Reusable canon pattern: {artifact.title}."
|
||||
if artifact.kind == "profile-alignment":
|
||||
|
||||
@@ -53,8 +53,12 @@ REQUIRED_SCHEMAS = (
|
||||
)
|
||||
|
||||
RETRIEVAL_BRIEF_KINDS = {
|
||||
"access-descriptor-set",
|
||||
"benefit-analysis",
|
||||
"benchmark-findings",
|
||||
"benchmark-workspace",
|
||||
"capture-criteria",
|
||||
"caring-mapping",
|
||||
"comparison-frame",
|
||||
"comparison-report",
|
||||
"concept-catalog",
|
||||
@@ -69,6 +73,7 @@ RETRIEVAL_BRIEF_KINDS = {
|
||||
"mapping-expectation",
|
||||
"model",
|
||||
"model-extension",
|
||||
"native-concept-map",
|
||||
"pattern",
|
||||
"profile-alignment",
|
||||
"profile",
|
||||
@@ -243,6 +248,40 @@ REPO_SCOPING_REQUIRED_EXTENSION_CANDIDATES = {
|
||||
"extension/scope-md-interface",
|
||||
}
|
||||
|
||||
CARING_K8S_BENCHMARK_ARTIFACT_IDS = {
|
||||
"benchmark/caring/kubernetes-rbac",
|
||||
"benchmark/caring/kubernetes-rbac/access-descriptors",
|
||||
"benchmark/caring/kubernetes-rbac/caring-mapping",
|
||||
"benchmark/caring/kubernetes-rbac/findings",
|
||||
"benchmark/caring/kubernetes-rbac/native-concepts",
|
||||
}
|
||||
|
||||
CARING_K8S_REQUIRED_NATIVE_CONCEPTS = {
|
||||
"Role",
|
||||
"ClusterRole",
|
||||
"RoleBinding",
|
||||
"ClusterRoleBinding",
|
||||
"ServiceAccount",
|
||||
"Namespace",
|
||||
"Verb",
|
||||
"Resource",
|
||||
"Scope",
|
||||
}
|
||||
|
||||
CARING_K8S_REQUIRED_CASES = {
|
||||
"namespace-pod-reader",
|
||||
"workload-creator-derived-execution",
|
||||
"cluster-secret-reader",
|
||||
"namespace-as-tenant-boundary",
|
||||
}
|
||||
|
||||
CARING_K8S_REQUIRED_DESCRIPTOR_CLASSES = {
|
||||
"declared_access",
|
||||
"effective_access",
|
||||
"derived_capability",
|
||||
"induced_access",
|
||||
}
|
||||
|
||||
|
||||
def structural_checks(context: Any) -> dict[str, list[dict[str, Any]]]:
|
||||
errors: list[dict[str, Any]] = []
|
||||
@@ -270,6 +309,11 @@ def structural_checks(context: Any) -> dict[str, list[dict[str, Any]]]:
|
||||
context.infospace.artifacts,
|
||||
errors,
|
||||
)
|
||||
_check_caring_kubernetes_rbac_benchmark_assets(
|
||||
context.infospace_root,
|
||||
context.infospace.artifacts,
|
||||
errors,
|
||||
)
|
||||
_check_optional_assets(context.infospace_root, warnings)
|
||||
|
||||
return {"errors": errors, "warnings": warnings}
|
||||
@@ -1167,6 +1211,216 @@ def _check_repo_scoping_comparison_assets(
|
||||
)
|
||||
|
||||
|
||||
def _check_caring_kubernetes_rbac_benchmark_assets(
|
||||
infospace_root: Path,
|
||||
artifacts: list[Any],
|
||||
errors: list[dict[str, Any]],
|
||||
) -> None:
|
||||
artifact_ids = {artifact.id for artifact in artifacts}
|
||||
for artifact_id in sorted(CARING_K8S_BENCHMARK_ARTIFACT_IDS - artifact_ids):
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_rbac_benchmark_artifact",
|
||||
"artifact_id": artifact_id,
|
||||
}
|
||||
)
|
||||
|
||||
benchmark_root = infospace_root / "standards" / "caring" / "benchmarks" / "kubernetes-rbac"
|
||||
if not benchmark_root.is_dir():
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_rbac_benchmark_workspace",
|
||||
"path": "infospace/standards/caring/benchmarks/kubernetes-rbac",
|
||||
}
|
||||
)
|
||||
return
|
||||
|
||||
benchmark = _read_yaml(benchmark_root / "benchmark.yaml", errors)
|
||||
if isinstance(benchmark, dict):
|
||||
for field in ("source_corpus", "expected_outputs", "review_criteria"):
|
||||
items = benchmark.get(field) or []
|
||||
if not isinstance(items, list) or not items:
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_benchmark_field",
|
||||
"field": field,
|
||||
}
|
||||
)
|
||||
cases = benchmark.get("cases") or []
|
||||
if not isinstance(cases, list):
|
||||
errors.append(
|
||||
{
|
||||
"code": "invalid_caring_kubernetes_benchmark_cases",
|
||||
"path": "infospace/standards/caring/benchmarks/kubernetes-rbac/benchmark.yaml",
|
||||
}
|
||||
)
|
||||
else:
|
||||
case_ids = {
|
||||
str(case.get("id"))
|
||||
for case in cases
|
||||
if isinstance(case, dict) and case.get("id")
|
||||
}
|
||||
for case_id in sorted(CARING_K8S_REQUIRED_CASES - case_ids):
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_benchmark_case",
|
||||
"case": case_id,
|
||||
}
|
||||
)
|
||||
|
||||
native = _read_yaml(benchmark_root / "native-concepts.yaml", errors)
|
||||
if isinstance(native, dict):
|
||||
if native.get("namespace_tenant_boundary_warning") is not True:
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_namespace_warning",
|
||||
"path": "infospace/standards/caring/benchmarks/kubernetes-rbac/native-concepts.yaml",
|
||||
}
|
||||
)
|
||||
concepts = native.get("concepts") or []
|
||||
if not isinstance(concepts, list):
|
||||
errors.append(
|
||||
{
|
||||
"code": "invalid_caring_kubernetes_native_concepts",
|
||||
"path": "infospace/standards/caring/benchmarks/kubernetes-rbac/native-concepts.yaml",
|
||||
}
|
||||
)
|
||||
else:
|
||||
native_names = {
|
||||
str(concept.get("native"))
|
||||
for concept in concepts
|
||||
if isinstance(concept, dict) and concept.get("native")
|
||||
}
|
||||
for concept in sorted(CARING_K8S_REQUIRED_NATIVE_CONCEPTS - native_names):
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_native_concept",
|
||||
"concept": concept,
|
||||
}
|
||||
)
|
||||
|
||||
mapping = _read_yaml(benchmark_root / "caring-mapping.yaml", errors)
|
||||
if isinstance(mapping, dict):
|
||||
if mapping.get("namespace_tenant_boundary_warning") is not True:
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_mapping_namespace_warning",
|
||||
"path": "infospace/standards/caring/benchmarks/kubernetes-rbac/caring-mapping.yaml",
|
||||
}
|
||||
)
|
||||
mappings = mapping.get("mappings") or []
|
||||
if not isinstance(mappings, list):
|
||||
errors.append(
|
||||
{
|
||||
"code": "invalid_caring_kubernetes_mappings",
|
||||
"path": "infospace/standards/caring/benchmarks/kubernetes-rbac/caring-mapping.yaml",
|
||||
}
|
||||
)
|
||||
else:
|
||||
mapped_names = {
|
||||
str(item.get("native_concept"))
|
||||
for item in mappings
|
||||
if isinstance(item, dict) and item.get("native_concept")
|
||||
}
|
||||
for concept in sorted(CARING_K8S_REQUIRED_NATIVE_CONCEPTS - mapped_names):
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_mapping",
|
||||
"concept": concept,
|
||||
}
|
||||
)
|
||||
analysis_rules = mapping.get("analysis_rules") or []
|
||||
if not isinstance(analysis_rules, list) or not analysis_rules:
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_analysis_rules",
|
||||
"path": "infospace/standards/caring/benchmarks/kubernetes-rbac/caring-mapping.yaml",
|
||||
}
|
||||
)
|
||||
|
||||
descriptors = _read_yaml(benchmark_root / "access-descriptors.yaml", errors)
|
||||
if isinstance(descriptors, dict):
|
||||
descriptor_classes = set(descriptors.get("descriptor_classes") or [])
|
||||
for descriptor_class in sorted(
|
||||
CARING_K8S_REQUIRED_DESCRIPTOR_CLASSES - descriptor_classes
|
||||
):
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_descriptor_class",
|
||||
"descriptor_class": descriptor_class,
|
||||
}
|
||||
)
|
||||
descriptor_items = descriptors.get("descriptors") or []
|
||||
if not isinstance(descriptor_items, list):
|
||||
errors.append(
|
||||
{
|
||||
"code": "invalid_caring_kubernetes_descriptors",
|
||||
"path": "infospace/standards/caring/benchmarks/kubernetes-rbac/access-descriptors.yaml",
|
||||
}
|
||||
)
|
||||
else:
|
||||
used_classes = {
|
||||
str(item.get("descriptor_class"))
|
||||
for item in descriptor_items
|
||||
if isinstance(item, dict) and item.get("descriptor_class")
|
||||
}
|
||||
for descriptor_class in sorted(
|
||||
CARING_K8S_REQUIRED_DESCRIPTOR_CLASSES - used_classes
|
||||
):
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_descriptor_example",
|
||||
"descriptor_class": descriptor_class,
|
||||
}
|
||||
)
|
||||
required_fields = (
|
||||
"subject",
|
||||
"scope",
|
||||
"plane",
|
||||
"capabilities",
|
||||
"exposure_mode",
|
||||
"lifecycle_state",
|
||||
"native_evidence",
|
||||
)
|
||||
for item in descriptor_items:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
for field in required_fields:
|
||||
if not item.get(field):
|
||||
errors.append(
|
||||
{
|
||||
"code": "incomplete_caring_kubernetes_descriptor",
|
||||
"descriptor": item.get("id"),
|
||||
"field": field,
|
||||
}
|
||||
)
|
||||
|
||||
findings = _read_yaml(benchmark_root / "findings-and-canon-pressure.yaml", errors)
|
||||
if isinstance(findings, dict):
|
||||
for field in ("stable_findings", "gaps", "conflicts", "proposed_changes"):
|
||||
items = findings.get(field) or []
|
||||
if not isinstance(items, list) or not items:
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_findings_field",
|
||||
"field": field,
|
||||
}
|
||||
)
|
||||
stable_findings = findings.get("stable_findings") or []
|
||||
finding_ids = {
|
||||
str(finding.get("id"))
|
||||
for finding in stable_findings
|
||||
if isinstance(finding, dict) and finding.get("id")
|
||||
}
|
||||
if "finding/namespace-not-tenant-boundary" not in finding_ids:
|
||||
errors.append(
|
||||
{
|
||||
"code": "missing_caring_kubernetes_namespace_finding",
|
||||
"path": "infospace/standards/caring/benchmarks/kubernetes-rbac/findings-and-canon-pressure.yaml",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _artifact_paths_by_path(
|
||||
infospace_root: Path,
|
||||
errors: list[dict[str, Any]],
|
||||
|
||||
Reference in New Issue
Block a user