You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug(secrets): C1 blocked — SLM cannot authenticate to System-vault /system routes (#10436 HMAC service-auth vs SLM X-Internal-API-Key, no signer) #10492
Phase C1 (#10153) — migrate SLM SSO client secrets into autobot-backend's unified-secrets System vault — is blocked by an authentication-scheme mismatch in the System-vault service path delivered by #10436 (merged in PR #10478).
The /api/v2/secrets/system/* routes authenticate the caller via service_principal → validate_service_auth, which requires HMAC X-Service-ID / X-Service-Signature / X-Service-Timestamp headers signed with a per-service key stored in Redis (service:key:{service_id}).
The SLM (autobot-slm-backend) — the intended non-user caller — has no HMAC service-auth signer. Its only cross-backend credential is the shared X-Internal-API-Key (AUTOBOT_INTERNAL_API_KEY, validated in autobot-backend/auth_middleware.py:819 and api/auth.py:702, sent by autobot-slm-backend/api/voice_proxy.py). There is no provisioned service:key:slm-backend and no code path that signs X-Service-* requests.
Net:#10436's "System vault for non-user callers" path is, as merged, not callable by the SLM — defeating its stated purpose ("SLM=system/no-user can't call → needs System-vault service-auth path").
SLM has no signer: grep -rn "X-Service-(ID|Signature)|validate_service_auth" autobot-slm-backend/ → only a doc-string mention in models/manifest.py.
SLM's actual credential: autobot-slm-backend/api/voice_proxy.py (X-Internal-API-Key: AUTOBOT_INTERNAL_API_KEY).
Why this is the §4.1 surface
The enterprise-SSO design (docs/superpowers/specs/2026-06-15-enterprise-sso-federation-design.md §4.1) explicitly flags the cross-backend boundary as a Phase C prerequisite to settle with the #10088 owner before C1. #10436 picked HMAC service-auth without wiring an SLM-side signer or deploy-time key provisioning, so the surface is still unsettled.
Resolution options (owner decision)
Option A — accept X-Internal-API-Key on the /system routes. Map the existing shared key to a synthetic service_id (e.g. slm-backend). Reuses already-provisioned credentials (zero deploy change), minimal surface. Trade-off: one shared key, coarser than per-service HMAC + replay protection.
Option B — give the SLM an HMAC service-auth signer + provision service:key:slm-backend. Per-service key, 5-min replay window, more granular. Trade-off: new SLM signing client + deploy-time key provisioning (Redis + role manifest), larger surface.
Acceptance
Integration surface decided + documented in the spec (§4.1).
SLM can authenticate to /api/v2/secrets/system/* end-to-end (proven with a round-trip).
Update — surface is smaller than first assessed; resolution = Option B (per-service HMAC), foundation mostly exists
The HMAC service-auth infra is already shared and tested — no new crypto and no new auth scheme are needed:
Shared signer already exists:autobot_shared/http_client.py:sign_request(service_id, service_key, method, path, timestamp) produces exactly the X-Service-ID/Signature/Timestamp headers that autobot-backend/security/service_auth.py:ServiceAuthManager.validate_signature checks. Pure, no-I/O, importable from the SLM.
Key provisioning already exists:autobot-infrastructure/shared/scripts/generate_service_keys.py mints service:key:{id} into Redis; export_service_keys.py exports per-service .env files for Ansible; a service loads its own key via SERVICE_KEY env → config.service_key (ssot_config.py:1546).
Precise remaining gaps (all additive):
slm-backend is absent from the SERVICES lists in generate_service_keys.py and export_service_keys.py → add it so its key is minted + exported.
No SLM-side client calls the /api/v2/secrets/system/* routes → add autobot-slm-backend/services/secrets_vault_client.py that signs with the shared sign_request using service_id="slm-backend" + config.service_key, base URL AUTOBOT_BACKEND_URL.
Deploy: distribute the minted key to the SLM .env via the existing export mechanism.
Resolution is folded into C1 (#10153): the vault client is wired into SSOSecretsManager behind a default-off backend selector with backward-compatible local reads, so existing deployments are unchanged until the key is provisioned. Closing criteria unchanged (round-trip proof that an SLM-signed request passes validate_signature and reaches a /system route).
Activity
mrveiss commentedon Jun 26, 2026
Update — surface is smaller than first assessed; resolution = Option B (per-service HMAC), foundation mostly exists
The HMAC service-auth infra is already shared and tested — no new crypto and no new auth scheme are needed:
autobot_shared/http_client.py:sign_request(service_id, service_key, method, path, timestamp)produces exactly theX-Service-ID/Signature/Timestampheaders thatautobot-backend/security/service_auth.py:ServiceAuthManager.validate_signaturechecks. Pure, no-I/O, importable from the SLM.autobot-infrastructure/shared/scripts/generate_service_keys.pymintsservice:key:{id}into Redis;export_service_keys.pyexports per-service.envfiles for Ansible; a service loads its own key viaSERVICE_KEYenv →config.service_key(ssot_config.py:1546).Precise remaining gaps (all additive):
slm-backendis absent from theSERVICESlists ingenerate_service_keys.pyandexport_service_keys.py→ add it so its key is minted + exported./api/v2/secrets/system/*routes → addautobot-slm-backend/services/secrets_vault_client.pythat signs with the sharedsign_requestusingservice_id="slm-backend"+config.service_key, base URLAUTOBOT_BACKEND_URL..envvia the existing export mechanism.Resolution is folded into C1 (#10153): the vault client is wired into
SSOSecretsManagerbehind a default-off backend selector with backward-compatible local reads, so existing deployments are unchanged until the key is provisioned. Closing criteria unchanged (round-trip proof that an SLM-signed request passesvalidate_signatureand reaches a/systemroute).feat(sso): migrate SSO secrets to unified vault + rotation (#10153, #…
github-actions commentedon Jun 26, 2026
PR #10498 (merged to
Dev_new_gui) references this issue with a close keyword.If this issue is fully resolved, close it manually. If work remains, no action is needed.
fix(secrets): accept X-Internal-API-Key on System-vault routes (Optio…
github-actions commentedon Jun 27, 2026
PR #10558 (merged to
Dev_new_gui) references this issue with a close keyword.If this issue is fully resolved, close it manually. If work remains, no action is needed.
mrveiss commentedon Jun 27, 2026
Merged to
Dev_new_gui(1040d6490, PR #10558). Option A implemented: backendservice_principalaccepts the sharedX-Internal-API-Key(→ syntheticservice_id=slm-backend, System-vault scoping preserved); SLMunified_vault_clientsends it +is_configured()gates onAUTOBOT_INTERNAL_API_KEY. Documented in design spec §4.1. Unblocks #10153/#10154. Batch #10440.