Send a caller identity to flex-auth so policy.enabled can flip
flex-auth's flex-auth-ops-warden pin (FLEX-WP-0016) TokenReviews the caller and binds resource.system: ops-warden to system:serviceaccount:ops-warden:ops-warden. policy.py posted /v1/check with no Authorization header, so the pin logs "caller authentication warning" and can only run callerAuth.mode: warn — which, under ADHOC-2026-08-17-T01, is exactly what blocks policy.enabled: true. - policy.caller_auth (none | file | env | command) + src/warden/caller_identity.py: token resolved per call, never cached, written, or logged (ADR-0002) - both check_sign_policy and check_fetch_policy attach the bearer header; an unobtainable token fails closed rather than retrying anonymously - scripts/check_policy_caller_identity.py: read-only gate, prints length and a truncated fingerprint only, distinguishes 401 (audience/binding) from 403 - example config: caller_auth block, and flex_auth_url corrected — it pointed at flex-auth.flex-auth.svc, a Service that does not exist - WARDEN-WP-0031, PolicyGatedSigning caller-identity section and flip sequence Default stays mode: none, so behaviour is unchanged until an operator opts in. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
35aff380a3
commit
0a331413a2
9 changed files with 728 additions and 12 deletions
|
|
@ -8,6 +8,7 @@ from pathlib import Path
|
|||
import httpx
|
||||
|
||||
from warden.ca import CAError
|
||||
from warden.caller_identity import CallerIdentityError, caller_auth_headers
|
||||
from warden.config import PolicyConfig
|
||||
from warden.models import CertSpec
|
||||
|
||||
|
|
@ -19,6 +20,21 @@ def pubkey_fingerprint(pubkey_path: Path) -> str:
|
|||
return f"sha256:{digest}"
|
||||
|
||||
|
||||
def _caller_headers(cfg: PolicyConfig) -> dict[str, str]:
|
||||
"""Bearer header identifying ops-warden itself to flex-auth (FLEX-WP-0016).
|
||||
|
||||
When the token cannot be obtained we refuse the call under ``fail_closed``
|
||||
rather than silently falling back to an unauthenticated request — an
|
||||
unauthenticated call is exactly what keeps the flex-auth pin in ``warn``.
|
||||
"""
|
||||
try:
|
||||
return caller_auth_headers(cfg.caller_auth)
|
||||
except CallerIdentityError as e:
|
||||
if cfg.fail_closed:
|
||||
raise CAError(f"flex-auth caller identity unavailable: {e}") from e
|
||||
return {}
|
||||
|
||||
|
||||
def _subject_id(cfg: PolicyConfig, spec: CertSpec) -> str:
|
||||
return os.environ.get(cfg.subject_env, "").strip() or spec.actor_name
|
||||
|
||||
|
|
@ -60,8 +76,9 @@ def check_sign_policy(cfg: PolicyConfig, spec: CertSpec) -> str | None:
|
|||
}
|
||||
|
||||
url = cfg.flex_auth_url.rstrip("/") + "/v1/check"
|
||||
headers = _caller_headers(cfg)
|
||||
try:
|
||||
response = httpx.post(url, json=request, timeout=10.0)
|
||||
response = httpx.post(url, json=request, headers=headers, timeout=10.0)
|
||||
response.raise_for_status()
|
||||
except httpx.HTTPStatusError as e:
|
||||
if cfg.fail_closed:
|
||||
|
|
@ -120,8 +137,9 @@ def check_fetch_policy(
|
|||
}
|
||||
|
||||
url = cfg.flex_auth_url.rstrip("/") + "/v1/check"
|
||||
headers = _caller_headers(cfg)
|
||||
try:
|
||||
response = httpx.post(url, json=request, timeout=10.0)
|
||||
response = httpx.post(url, json=request, headers=headers, timeout=10.0)
|
||||
response.raise_for_status()
|
||||
except httpx.HTTPStatusError as e:
|
||||
if cfg.fail_closed:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue