Repository navigation
phase2(s12.d): SignerPolicy ConfigMap (Fulcio issuer + SAN allowlist) - #117
Merged
Merged
Conversation
Replaces the env-var path that S12.b used for cosign signer-identity policy with a watched cluster-scoped ConfigMap (azureclaw-signer-policy in the controller namespace). Env vars remain as an emergency-override fallback when the ConfigMap is absent; malformed ConfigMaps surface as SignerPolicyMalformed (no silent fallback). - New controller/src/signer_policy.rs: ConfigMap parser + watcher + SharedSignerPolicy holder (Arc<RwLock<state>>). Atomic rebuild on watch-restart; namespace-scoped Api + name field-selector keep the watch tightly bounded. - New FetchError::SignerPolicyMalformed variant + reason mapping. policy_fetcher::maybe_verify_allowlist now consults a process-global SharedSignerPolicy handle; new maybe_verify_allowlist_with_handle variant takes an injected handle for unit-test cleanliness. - Helm: new signer-policy-configmap.yaml template; signerPolicy values block (enabled, fulcioIssuers, sanPatterns) with sensible defaults for GitHub Actions OIDC + Entra workload identity. - Helm: controller deployment now wires POD_NAMESPACE / POD_NAME via downward API (previously only set conditionally for leader-election). - RBAC: unchanged — controller ClusterRole already grants get/list/watch on configmaps cluster-wide; new watcher fits within the existing rule with no broadening introduced. - 18 new unit tests; controller test count 383 -> 401. Workspace green; clippy clean; cargo fmt clean; helm lint clean; CLI typecheck + lint clean. Audit doc: docs/security-audits/2026-04-30-phase2-s12-d-signer-policy.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pal Lakatos-Toth (pallakatos)
force-pushed
the
phase2-s12-d-signerpolicy
branch
from
April 30, 2026 00:29
de40352 to
d2de209
Compare
Pal Lakatos-Toth (pallakatos)
added a commit
that referenced
this pull request
May 12, 2026
…#117) Replaces the env-var path that S12.b used for cosign signer-identity policy with a watched cluster-scoped ConfigMap (azureclaw-signer-policy in the controller namespace). Env vars remain as an emergency-override fallback when the ConfigMap is absent; malformed ConfigMaps surface as SignerPolicyMalformed (no silent fallback). - New controller/src/signer_policy.rs: ConfigMap parser + watcher + SharedSignerPolicy holder (Arc<RwLock<state>>). Atomic rebuild on watch-restart; namespace-scoped Api + name field-selector keep the watch tightly bounded. - New FetchError::SignerPolicyMalformed variant + reason mapping. policy_fetcher::maybe_verify_allowlist now consults a process-global SharedSignerPolicy handle; new maybe_verify_allowlist_with_handle variant takes an injected handle for unit-test cleanliness. - Helm: new signer-policy-configmap.yaml template; signerPolicy values block (enabled, fulcioIssuers, sanPatterns) with sensible defaults for GitHub Actions OIDC + Entra workload identity. - Helm: controller deployment now wires POD_NAMESPACE / POD_NAME via downward API (previously only set conditionally for leader-election). - RBAC: unchanged — controller ClusterRole already grants get/list/watch on configmaps cluster-wide; new watcher fits within the existing rule with no broadening introduced. - 18 new unit tests; controller test count 383 -> 401. Workspace green; clippy clean; cargo fmt clean; helm lint clean; CLI typecheck + lint clean. Audit doc: docs/security-audits/2026-04-30-phase2-s12-d-signer-policy.md Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the env-var path used by S12.b for cosign signer-identity policy with a watched cluster-scoped
SignerPolicyConfigMap (azureclaw-signer-policyin the controller namespace). The env-var path (AZURECLAW_SIGNER_FULCIO_ISSUERS/AZURECLAW_SIGNER_SAN_PATTERNS) remains as an emergency-override fallback that engages only when the ConfigMap is absent; a malformed ConfigMap surfaces as a newSignerPolicyMalformedcondition reason and does not silently fall back.Trust-model improvement: the cluster's identity-pinning policy is now a first-class, watched, fail-closed configuration object that cluster-admins manage via Helm. Combined with S12.b (consumer verify) and S12.c (producer sign), the cluster has end-to-end coverage of "the bytes the operator sealed are the bytes the controller verifies — under an authority the operator has explicitly trusted." S12.e now has a reliable
SignerPolicyto flip authoritative-ref mode against.Surveyed seams (reused, not parallel-implemented)
controller/src/policy_fetcher.rs—SignerPolicyConfig,FetchError,reason_for_error,maybe_verify_allowlist. Added theSignerPolicyMalformedvariant + reason; rewiredmaybe_verify_allowlistto consult aSharedSignerPolicyhandle.controller/src/leader_election.rs—POD_NAMESPACEdownward-API idiom; reused. The Helmcontroller-deployment.yamlwas extended to wirePOD_NAMESPACE+POD_NAME(previously only relied on with a hard-coded fallback).controller/src/status/conditions.rs—TYPE_ALLOWLIST_VERIFIED,preserve_transition_time. The new reason is a literal returned byreason_for_error, matching the existing pattern.deploy/helm/azureclaw/templates/rbac.yaml— controllerClusterRolealready grantsget/list/watchonconfigmaps; no broadening introduced.Key safety properties (locked in by tests)
SignerPolicyMissing(absent + env-empty) → fail closed.SignerPolicyMalformed(ConfigMap broken) → fail closed; does not fall back to env (testwith_handle_malformed_does_not_fall_back_to_env).with_handle_configmap_takes_precedence_over_env).Test delta
Controller tests: 383 → 401 (+18). Breakdown:
controller/src/signer_policy.rs(parser strict-rejection cases +SharedSignerPolicyapply/clear/snapshot/clone semantics).controller/src/policy_fetcher.rsexercisingmaybe_verify_allowlist_with_handlefor eachSignerPolicyState(FromConfigMap precedence, Malformed surfaces SignerPolicyMalformed without env fallback, Absent falls back to env).reason_for_error_maps_each_varianttest.Existing env-fallback tests are preserved unchanged (the env path remains a documented emergency-override).
CI
cargo fmt --allcleancargo clippy --all-targets -- -D warningscleancargo test --all— all green (controller 401, router 608, others unchanged)helm lint deploy/helm/azureclawcleannpm run lint+npx tsc --noEmitcleanAudit doc
docs/security-audits/2026-04-30-phase2-s12-d-signer-policy.md— covers the threat (signer-key misconfiguration → forged allowlist accepted), mitigations (cluster-scoped ConfigMap; controller-only watch; namespace-scopedApi+ name field-selector; malformed-detection condition; env fallback for emergency override), and a surveyed-existing-implementation section listing every reused seam.Plan slot
§S12.d — "identity-pinned verification config. Cluster-level SignerPolicy ConfigMap (watched by controller) listing allowed Fulcio issuer + SAN patterns. Default config provided for GitHub Actions OIDC + Entra workload-identity issuers." Default config now lives in
deploy/helm/azureclaw/values.yamlundersignerPolicy.*.Out of scope (per slice spec)
allowedEndpoints;AllowlistVerifiedremains status-only.SignerPolicyper cluster.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com