Some checks failed
CI/CD / lint (pull_request) Successful in 1m19s
CI/CD / typecheck (pull_request) Successful in 2m44s
CI/CD / test (pull_request) Successful in 1m30s
CI/CD / build (pull_request) Successful in 2m23s
CI/CD / smoke (pull_request) Failing after 3m4s
CI/CD / publish (pull_request) Has been skipped
Found by the readiness probe added in the previous commit, on its first run against production: `mcpctl status` reported Secrets: bao-k8s* ✗ auth failed: OpenBao list: HTTP 400 Bad Request That is a real bug, not a probe artifact. `bao-k8s` is configured with the public ingress URL, and Cilium's ingress Envoy rejects the non-standard LIST HTTP method outright. Verified live from the mcpd pod: LIST https://bao.ad.itaz.eu/v1/secret/metadata/mcpctl/ -> 400 Bad Request GET https://bao.ad.itaz.eu/v1/secret/metadata/mcpctl/?list=true -> 403 permission denied (bogus token, i.e. reached bao) LIST http://openbao.openbao.svc:8200/... (ClusterIP, no Envoy) -> 403 permission denied So the verb was fine against bao and fatal through the ingress. OpenBao accepts both forms and documents the GET form for exactly this reason. This was never noticed because nothing called list() in production — it backs `mcpctl migrate secrets`, which would have failed with an opaque HTTP 400 against any ingress-fronted backend. Also adds the per-server scoping primitives Phase 2 needs, with tests: buildServerSecretPolicyHcl (no wildcards, read-only, stable under reordering), buildServerProvisioningPolicyHcl (prefix-confined so mcpd cannot grant itself more than it holds), ensureKubernetesAuthRole / delete helpers, the driver-level ensureServerIdentity/removeServerIdentity capability, and ServerIdentityService. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018vybEitX4FykeMatKe5Xki