Advance dependency roots with guarded source implementations
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a10391-6355-7b41-b0fa-3e14e874f091
This commit is contained in:
parent
20eef043ed
commit
9d10fba4cb
5 changed files with 263 additions and 8 deletions
|
|
@ -76,6 +76,107 @@ class KubernetesKVSpec:
|
|||
bao_bin: str = "bao"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class OIDCKVSpec:
|
||||
"""Attended four-entry operator matrix; all identity evidence is reviewed input."""
|
||||
policy_name: str
|
||||
role_name: str
|
||||
campaign_path: str
|
||||
bound_group: str
|
||||
allowed_redirect_uris: tuple[str, ...]
|
||||
identity_confirmation_ref: str
|
||||
platform_matrix_review_ref: str
|
||||
auth_mount: str = "netkingdom"
|
||||
token_ttl: str = "15m"
|
||||
token_max_ttl: str = "30m"
|
||||
bao_bin: str = "bao"
|
||||
audit_log_path: Path | None = None
|
||||
|
||||
|
||||
_OPERATOR_MATRIX = (
|
||||
("operator-app", ("read",)),
|
||||
("operator-session", ("create", "read", "update")),
|
||||
("bot-token", ("create", "read", "update")),
|
||||
("redaction-salt", ("create", "read")),
|
||||
)
|
||||
|
||||
|
||||
def oidc_policy_hcl(spec: OIDCKVSpec) -> str:
|
||||
"""Render exact KV data paths plus self-revocation; no metadata grants."""
|
||||
_validate_oidc_spec(spec)
|
||||
mount, rest = spec.campaign_path.split("/", 1)
|
||||
stanzas = []
|
||||
for entry, caps in _OPERATOR_MATRIX:
|
||||
encoded = ", ".join(json.dumps(c) for c in caps)
|
||||
stanzas.append(f'path "{mount}/data/{rest}/{entry}" {{\n capabilities = [{encoded}]\n}}\n')
|
||||
stanzas.append('path "auth/token/revoke-self" {\n capabilities = ["update"]\n}\n')
|
||||
return "\n".join(stanzas)
|
||||
|
||||
|
||||
def _validate_oidc_spec(spec: OIDCKVSpec) -> None:
|
||||
from urllib.parse import urlsplit
|
||||
for value, label in ((spec.role_name, "OIDC role"), (spec.auth_mount, "auth mount"),
|
||||
(spec.bound_group, "bound group")):
|
||||
_name(value, label)
|
||||
if not isinstance(spec.campaign_path, str):
|
||||
raise BuildRefused("campaign path must be literal")
|
||||
parts = spec.campaign_path.split("/")
|
||||
if len(parts) != 5 or parts[0:2] != ["platform", "workloads"] or parts[3] != "fluid-telegram":
|
||||
raise BuildRefused("operator matrix requires platform/workloads/<tenant>/fluid-telegram/<campaign>")
|
||||
for part in parts:
|
||||
_name(part, "campaign path segment")
|
||||
for ref in (spec.identity_confirmation_ref, spec.platform_matrix_review_ref):
|
||||
if not isinstance(ref, str) or not ref.strip() or ref.strip().lower() in {"pending", "unconfirmed", "unknown", "draft"}:
|
||||
raise BuildRefused("confirmed identity and platform matrix review references are required")
|
||||
ttl, maximum = _duration(spec.token_ttl, "token_ttl"), _duration(spec.token_max_ttl, "token_max_ttl")
|
||||
if not 0 < ttl <= 900 or not ttl <= maximum <= 1800:
|
||||
raise BuildRefused("attended OIDC token bounds must be at most 15m/30m")
|
||||
if not isinstance(spec.allowed_redirect_uris, tuple) or not spec.allowed_redirect_uris:
|
||||
raise BuildRefused("explicit OIDC callback tuple required")
|
||||
if len(set(spec.allowed_redirect_uris)) != len(spec.allowed_redirect_uris):
|
||||
raise BuildRefused("duplicate OIDC callback")
|
||||
for uri in spec.allowed_redirect_uris:
|
||||
if not isinstance(uri, str):
|
||||
raise BuildRefused("OIDC callback must be a URI")
|
||||
try:
|
||||
u = urlsplit(uri)
|
||||
valid = (u.scheme == "http" and u.hostname in {"localhost", "127.0.0.1"}
|
||||
and u.port == 8250 and u.path == "/oidc/callback" and not u.username
|
||||
and not u.password and not u.query and not u.fragment)
|
||||
except ValueError:
|
||||
valid = False
|
||||
if not valid:
|
||||
raise BuildRefused("initial matrix engine accepts only reviewed loopback CLI callbacks on port 8250")
|
||||
|
||||
|
||||
def oidc_role_document(spec: OIDCKVSpec) -> dict:
|
||||
_validate_oidc_spec(spec)
|
||||
return {
|
||||
"role_type": "oidc", "user_claim": "sub", "groups_claim": "groups",
|
||||
"oidc_scopes": ["openid", "profile", "email", "groups"],
|
||||
"bound_claims": {"groups": spec.bound_group},
|
||||
"allowed_redirect_uris": list(spec.allowed_redirect_uris),
|
||||
"token_policies": [spec.policy_name], "token_no_default_policy": True,
|
||||
"token_ttl": spec.token_ttl, "token_max_ttl": spec.token_max_ttl,
|
||||
"token_explicit_max_ttl": spec.token_max_ttl, "token_num_uses": 0,
|
||||
}
|
||||
|
||||
|
||||
def build_oidc_kv_lane(plan: ConstructionPlan, spec: OIDCKVSpec) -> dict[str, str]:
|
||||
"""Write only policy/auth structure after fresh exact-spec approval."""
|
||||
spec = replace(spec)
|
||||
plan = _approved_build(plan, spec)
|
||||
_run(spec.bao_bin, ["policy", "write", spec.policy_name, "-"], input_text=oidc_policy_hcl(spec))
|
||||
_run(spec.bao_bin, ["write", f"auth/{spec.auth_mount}/role/{spec.role_name}", "-"],
|
||||
input_text=json.dumps(oidc_role_document(spec)))
|
||||
objects = {"approved_spec_sha256": plan.approved_spec_sha256,
|
||||
"policy_name": spec.policy_name, "oidc_role_name": spec.role_name,
|
||||
"campaign_path": spec.campaign_path}
|
||||
record_build(plan_id=plan.id, plan_path=str(plan.path), approved_by=plan.approved_by or "",
|
||||
approved_at=plan.approved_at or "", objects=objects, log_path=spec.audit_log_path)
|
||||
return objects
|
||||
|
||||
|
||||
def _run(bao_bin: str, args: list[str], input_text: str | None = None) -> str:
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
|
|
@ -131,7 +232,7 @@ def _hash(value: str) -> None:
|
|||
raise BuildRefused("reused policy requires an exact SHA-256 content pin")
|
||||
|
||||
|
||||
def _validate_spec(spec: AppRoleKVSpec | KubernetesKVSpec) -> None:
|
||||
def _validate_spec(spec: AppRoleKVSpec | KubernetesKVSpec | OIDCKVSpec) -> None:
|
||||
_name(spec.policy_name, "policy name")
|
||||
_duration(spec.token_ttl, "token_ttl")
|
||||
if not isinstance(spec.bao_bin, str) or not spec.bao_bin.strip():
|
||||
|
|
@ -160,6 +261,8 @@ def _validate_spec(spec: AppRoleKVSpec | KubernetesKVSpec) -> None:
|
|||
spec.delivery_dir, spec.delivery_dir / "role_id", spec.delivery_dir / "secret_id"
|
||||
}:
|
||||
raise BuildRefused("audit path must not overlap credential delivery")
|
||||
elif isinstance(spec, OIDCKVSpec):
|
||||
_validate_oidc_spec(spec)
|
||||
else:
|
||||
_name(spec.role_name, "Kubernetes role name")
|
||||
_hash(spec.policy_sha256)
|
||||
|
|
@ -173,7 +276,7 @@ def _validate_spec(spec: AppRoleKVSpec | KubernetesKVSpec) -> None:
|
|||
raise BuildRefused("duplicate service account binding")
|
||||
|
||||
|
||||
def build_spec_document(spec: AppRoleKVSpec | KubernetesKVSpec) -> dict:
|
||||
def build_spec_document(spec: AppRoleKVSpec | KubernetesKVSpec | OIDCKVSpec) -> dict:
|
||||
"""Render the complete, value-free execution input for phase-3 review."""
|
||||
_validate_spec(spec)
|
||||
fields = asdict(spec)
|
||||
|
|
@ -183,7 +286,7 @@ def build_spec_document(spec: AppRoleKVSpec | KubernetesKVSpec) -> dict:
|
|||
elif isinstance(value, tuple):
|
||||
fields[key] = list(value)
|
||||
return {
|
||||
"engine": "openbao-approle-kv" if isinstance(spec, AppRoleKVSpec) else "openbao-kubernetes-kv",
|
||||
"engine": "openbao-approle-kv" if isinstance(spec, AppRoleKVSpec) else "openbao-oidc-kv-read-write" if isinstance(spec, OIDCKVSpec) else "openbao-kubernetes-kv",
|
||||
**fields,
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue