Raxx · internal docs

internal · gated

Vault Multi-Agent Access Pattern

Status: Proposed — awaiting operator direction on CF Access scope (see Open Questions) Date: 2026-06-20 UTC Author: software-architect ADR: 0130-vault-multi-agent-machine-identity Parent card: see sub-cards filed with this doc


1. Context

Raxx's secret store is self-hosted Infisical at vault.raxx.app, fronted by Cloudflare Access (non_identity service-token policy for machine callers; Google SSO for humans).

The current access model works, but it creates two classes of friction that compound as more agents and repos come online:

Friction class 1 — header tax. Every machine caller must obtain a CF Access service token and inject two headers (CF-Access-Client-Id, CF-Access-Client-Secret) on every request to vault. Most tool integrations (the Infisical MCP server, infisical CLI in CI, sdk-style calls from Raptor/Velvet) have no native facility to inject these headers. The workaround today: the main loop cannot call vault directly and must dispatch sre-agent for every secret one-shot. That is a 30-second tax per secret read.

Friction class 2 — shared identity. The current machine identity is effectively "one agent" for all agent reads. It cannot be scoped per agent class or per repo. If it is compromised, every secret every agent can see is exposed. Revoking it disrupts all agents simultaneously.

The operator has flagged the Infisical MCP server (https://github.com/Infisical/infisical-mcp-server) as a likely integration target. The MCP server authenticates via Infisical Universal Auth (client-id/secret → short-lived token). It cannot send CF Access headers — so as long as CF Access gates the vault API, the MCP server cannot work without a shim.

This document designs the steady-state vault access pattern for the multi-agent, multi-repo world and recommends the path with the least security friction that does not sacrifice meaningful protection.


2. Invariants

The following system-level invariants apply to this design. No option may route around them.

# Invariant
I1 No stored credentials. The vault access pattern must not require any component to persist a credential value that can be replayed. Machine identity client secrets are credentials; they live in env/secret stores, never in files that ship.
I2 Passkeys / WebAuthn only for human authentication. This design is about machine-to-machine access; human vault access via the UI continues through CF Access + Google SSO.
I3 Audit trail for every state change that affects money, permissions, or data access. Secret reads must be auditable (Infisical provides an audit log per identity).
I4 Credentials into infra, not into code. Machine identity client IDs and secrets live in environment variables or Infisical itself (bootstrap identity only).
I5 GDPR by default. Any vault access log that records user-correlated data (e.g., which agent read which secret for which user request) must have a defined retention period and DSR deletion path.
I6 Security is a design constraint. The choice of CF Access posture is a security decision made here; it is not delegated to feature-developer.
I7 Velvet owns secret lifecycle (mint, rotation, revocation). The access pattern designed here is for reads and writes that are part of normal service operation; rotation events go through Velvet.

3. What Infisical Natively Provides as a Security Boundary

Before evaluating whether CF Access adds meaningful defense in depth, we must honestly assess what Infisical Universal Auth provides on its own.

3.1 Universal Auth machine identity

Each machine identity has:

3.2 Per-identity RBAC

Infisical's RBAC can scope a machine identity to:

A read-only identity with read on /MooseQuest/raptor/prod/ and no other permissions can read those secrets and nothing else. Even if the identity's access token is leaked, the attacker gets read access to exactly that path — no writes, no deletes, no other paths.

3.3 IP allowlists per identity

Infisical supports per-identity trusted IP ranges. A machine identity provisioned for GH Actions runners can be restricted to GitHub's published Actions runner IP ranges. An identity for a Heroku dyno can be restricted to Heroku's egress IP ranges. An identity for the operator workstation can be restricted to the operator's static IP or VPN exit range.

Limitation: IP ranges for ephemeral environments (GitHub Actions, Heroku dynos) are published but wide and change without notice. IP allowlisting is a complement, not a substitute for credential hygiene.

3.4 Token TTL

Access tokens expire. Short-lived tokens limit the blast radius of a leaked token. Infisical's minimum TTL is configurable; 15-minute access tokens with a 7-day refresh window is a reasonable baseline.

3.5 Audit log

Infisical writes an audit event for every secret read, write, and delete, tagged with the identity that performed the action. These logs are available in the Infisical UI and via API. For compliance, they should be exported (see §8 Security Considerations).

3.6 Assessment: is native auth sufficient as the primary control?

Yes, for machine-to-machine secret reads, with the following conditions met:

  1. Each agent/service has its own machine identity (least-privilege, not shared).
  2. Every identity is read-only by default; write is granted only where required.
  3. Identities are path-scoped, not project-wide.
  4. Access tokens have short TTL (15–60 minutes).
  5. Infisical itself (the application and its Postgres) is hardened separately (see §4.B).

The threat model for CF Access in front of vault is: "protect the Infisical UI and API from a network-level attacker who might exploit an Infisical application CVE before we can patch." That is a real threat, but the mitigation options extend beyond CF Access. Section 4 evaluates all options.


4. Network Exposure Options

Option A — Keep CF Access; add a header-injecting local proxy

Design: A thin localhost reverse proxy (single-binary or Docker sidecar) that accepts connections on 127.0.0.1:2019 and forwards to vault.raxx.app, injecting the CF-Access-Client-Id and CF-Access-Client-Secret headers from environment variables. All tools (Infisical MCP, Infisical CLI, SDK) point at http://localhost:2019 instead of https://vault.raxx.app.

tool/agent → localhost:2019 (proxy)
                  ↓  + CF-Access-Client-Id header
                  ↓  + CF-Access-Client-Secret header
              vault.raxx.app (CF Access gate + Infisical)

The proxy does not terminate TLS on the vault side — it proxies CONNECT or forwards HTTP headers. The CF Access service token for the proxy is a single identity per execution environment (one for CI, one for the operator workstation, one for each Heroku dyno class).

Security posture: - CF Access remains the outer gate. Infisical is not internet-reachable directly. - A leaked Infisical access token cannot be used by an external attacker without also possessing the CF Access service token. Two independent secrets required for any attack. - The proxy's CF Access service token is the choke point: if it is compromised, all traffic from that environment can be proxied. Rotate via Velvet.

Friction reduction: - The MCP server, CLI, and any future tool works with zero changes — just point at localhost. - The feedback_main_loop_vault_limit friction is resolved: main loop can call vault directly through the proxy without dispatching sre-agent. - Per-agent RBAC and scoping is still enforced at the Infisical layer.

Gaps: - The proxy is one more thing to run and maintain. It must be running for vault access. - Ephemeral GH Actions runners need the proxy started as a job step. A ~5-line pre-job step or action can handle this; it is not onerous. - The proxy must not log request bodies (credential values).

Verdict: Strong defense. Keeps the two-factor model (CF Access + Infisical auth). Removes the per-tool header burden. This is the recommended path if the operator wants to preserve CF Access as the outer gate.


Option B — Drop CF Access on the vault API path; Infisical native auth + IP allowlists + WAF

Design: Retire the CF Access non_identity policy for machine callers. Infisical is still behind Cloudflare's proxy (WAF, DDoS protection, rate limiting) but the CF Access gate is removed for API paths. Human access to the UI (/ui/*) retains CF Access + Google SSO. Machine callers authenticate directly with Infisical Universal Auth.

tool/agent → vault.raxx.app (CF WAF + Infisical, no CF Access gate for /api/*)
                  CF Access retained for /ui/* human paths only

Security posture: - Any Infisical CVE on the API surface is now directly reachable. The CF WAF (already planned — WAF strategy doc, ADR-0077) provides L7 filtering, but a WAF is not an application firewall; novel API vulnerabilities will not be in the managed ruleset. - Infisical's own auth (Universal Auth + RBAC + IP allowlists) is the primary control. - Mitigation: IP allowlist all machine identities to their execution environment egress ranges. Unknown-source attacks that lack a valid Infisical credential still fail. - Mitigation: Keep WAF managed ruleset + rate limiting on vault.raxx.app for volumetric and known-pattern attacks.

Friction reduction: - Maximum reduction. No proxy, no extra headers. MCP server works natively with INFISICAL_HOST_URL=https://vault.raxx.app. - Onboarding a new agent is: provision an Infisical machine identity, export INFISICAL_CLIENT_ID + INFISICAL_CLIENT_SECRET to the agent's environment.

Gaps: - Direct exposure of Infisical API to the internet (behind WAF only, not CF Access). Infisical self-hosted is a Flask/Node app; its API surface is non-trivial. - This is a net reduction in perimeter control. The trade is: lower operational friction in exchange for a wider blast radius on Infisical application vulnerabilities.

Verdict: Acceptable if Infisical is kept on current patch cadence and WAF is in block mode. Not the recommended primary path due to the increased CVE exposure window, but worth revisiting post-launch when operational cadence is established.


Option C — Private network / Cloudflare Tunnel / mesh (no public ingress)

Design: vault.raxx.app becomes a private hostname reachable only via a Cloudflare Tunnel (or Tailscale/WireGuard mesh). The tunnel is the ingress; the public DNS record resolves to a CNAME that only works if the caller has the tunnel client (cloudflared or Tailscale node) running.

Security posture: - Strongest perimeter: vault is not reachable from the public internet at all. - No Infisical API CVE is exploitable from outside the mesh. - Audit: all access goes through the tunnel, which logs connections.

Friction reduction (persistent services): - Raptor dynos, Velvet dynos: run cloudflared as a sidecar Procfile entry. Works, but adds a process to every dyno. - Operator workstation: install cloudflared or Tailscale once. Works seamlessly for persistent sessions.

Friction for ephemeral environments: - GH Actions runners: must install cloudflared or Tailscale and authenticate to the mesh on every runner spawn. Feasible (Tailscale has an official GH Action), but adds ~15–30 seconds to every CI job that needs vault access, and requires a mesh auth secret in GH Actions. - Claude Code sessions: each session must have cloudflared running. If the session is on the operator's machine, and the machine is on the mesh, this is transparent. If sessions run on remote compute, mesh access must be provisioned.

Verdict: Gold standard for perimeter but has real friction for CI and ad-hoc sessions. Best suited as a long-term upgrade path, not the immediate friction fix. Consider as Phase 2 once Option A is bedded in.


Option D — Hybrid: proxy for CI + narrow mesh for persistent services

Design: Persistent services (Raptor, Velvet, Console) access vault over a Cloudflare Tunnel (Option C). Ephemeral environments (GH Actions, operator workstation, Claude Code) use the local header-injecting proxy (Option A). CF Access service tokens are issued per execution environment class.

Security posture: Matches or exceeds Option A for all environments. Persistent services gain the mesh boundary. Ephemeral environments retain CF Access + Infisical auth.

Friction: Moderate. Two access patterns to maintain. Onboarding is: "are you a persistent service or an ephemeral client?" and you get the appropriate runbook.

Verdict: Architecturally sound, but operationally more complex than Option A. Good evolution target once Option A is stable and the tunnel infrastructure exists.


Primary: Option A (header-injecting local proxy) with per-agent machine identities.

Reasons:

  1. Preserves the two-factor model (CF Access + Infisical auth) that is currently in place. No regression in security posture.
  2. Fully resolves the MCP server compatibility gap and the feedback_main_loop_vault_limit sre-agent dispatch tax with a single thin proxy component.
  3. Onboarding a new agent is lightweight: provision a scoped machine identity in Infisical + point the tool at the proxy. No new infrastructure required.
  4. Option C (mesh) is a natural evolution: when Heroku dynos are stable and the operator wants to harden further, vault.raxx.app can be moved behind a tunnel. The per-agent machine identity design (§6) is identical whether the proxy or tunnel is the ingress — the Infisical layer is unchanged.

Operator decision required (OQ1): Does the operator want to retain CF Access as the outer gate (Option A), or is Infisical native auth sufficient on its own (Option B)? This is the single decision that must be made before the spike can be executed.


6. Per-Agent Machine Identity Model

Regardless of which network option is chosen, this is the core security boundary.

6.1 Identity naming convention

infisical-identity-{agent-class}-{repo-slug}

Examples: - infisical-identity-main-loop-trademaster - infisical-identity-sre-agent-trademaster - infisical-identity-ci-trademaster - infisical-identity-raptor-prod - infisical-identity-velvet-prod

6.2 Permission matrix

Identity Projects Paths Permissions
main-loop MooseQuest /MooseQuest/ (read-only, no billing subtrees) read
sre-agent MooseQuest /MooseQuest/ read, create, edit (no delete)
ci MooseQuest /MooseQuest/ci/ only read
raptor-prod MooseQuest /MooseQuest/raptor/prod/ read
raptor-staging MooseQuest /MooseQuest/raptor/staging/ read
velvet-prod MooseQuest /MooseQuest/velvet/prod/, /MooseQuest/ (write for rotation distribution) read, edit
queue-prod MooseQuest /MooseQuest/queue/prod/ read
infisical-mcp-main-loop MooseQuest /MooseQuest/ minus billing/payment paths read only

The infisical-mcp-main-loop identity is the dedicated identity for the MCP server integration (see §7). It is separate from the main-loop identity so the MCP server's access can be independently revoked without disrupting programmatic vault access.

6.3 Provisioning flow

  1. Operator (or Velvet with appropriate scopes) creates a new machine identity in Infisical via the admin API or UI.
  2. The identity's client_id and client_secret are stored in Infisical at /MooseQuest/identities/{identity-name}/ — yes, the identity secret is stored in vault, bootstrapped by the Velvet machine identity which has write access.
  3. The CI/CD pipeline or agent dispatch script reads the secret at spawn time (same pattern as scripts/agents/mint_github_token.py).
  4. On the execution environment, the identity is available as: - INFISICAL_CLIENT_ID - INFISICAL_CLIENT_SECRET - INFISICAL_PROJECT_ID - INFISICAL_HOST_URL

6.4 Rotation

Machine identity secrets are rotated via Velvet. Each identity registers as a consumer in the Velvet subscription manifest (docs/architecture/velvet/subscription-manifest.yml). Rotation follows the Velvet v2 operational flow (ADR-0037 through 0040): Stage 1 (verify) → Stage 2 (mint + distribute) → Stage 3 (validate + revoke).

6.5 Revocation

Independent. Revoking infisical-identity-main-loop-trademaster does not affect infisical-identity-raptor-prod. Each identity is a distinct Infisical entity.

6.6 Audit trail

Infisical logs every secret access per identity. Exporting these logs to the append-only audit chain (ADR-0022) is out of scope for the spike but should be a follow-on card.

6.7 Onboarding a new repo or agent

1. Create machine identity in Infisical with least-privilege scope
2. Store client_id + client_secret at /MooseQuest/identities/<name>/
3. Add to Velvet subscription manifest for rotation tracking
4. Set INFISICAL_CLIENT_ID + INFISICAL_CLIENT_SECRET in the new agent's env
5. (If Option A) Point tool at proxy endpoint instead of vault.raxx.app directly
6. Test: agent can read its allowed paths; cannot read other paths

7. Infisical MCP Server Integration Design

The Infisical MCP server (@infisical/mcp-server) exposes 11 tools: get-secret, list-secrets, create-secret, update-secret, delete-secret, list-projects, list-environments, list-folders, create-folder, get-folder, invite-member.

The gap: The server authenticates via Universal Auth — it cannot send CF Access headers. Under Option A (recommended), the proxy solves this: the server connects to http://localhost:2019, the proxy injects CF Access headers.

The read-only gap: The MCP server has no read-only mode switch. delete-secret and invite-members are always present in the tool list. Mitigation: the dedicated MCP identity (infisical-mcp-main-loop) has no delete or create permission at the Infisical RBAC layer. If the LLM calls delete-secret or create-secret or invite-member, Infisical returns 403. The tools are inert at the identity layer.

Run model: The MCP server runs as a session-scoped process, launched by npx:

// .claude/mcp_servers.json (or equivalent MCP config)
{
  "infisical": {
    "command": "npx",
    "args": ["-y", "@infisical/mcp-server"],
    "env": {
      "INFISICAL_UNIVERSAL_AUTH_CLIENT_ID": "${INFISICAL_CLIENT_ID}",
      "INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET": "${INFISICAL_CLIENT_SECRET}",
      "INFISICAL_HOST_URL": "http://localhost:2019"  // proxy endpoint (Option A)
    }
  }
}

Under Option B (if the operator selects it), INFISICAL_HOST_URL points directly to https://vault.raxx.app.

What this replaces: The feedback_main_loop_vault_limit constraint ("main loop cannot read vault directly → dispatch sre-agent"). With the MCP server wired, the main loop can call get-secret directly. The sre-agent dispatch for vault reads becomes unnecessary; sre-agent retains vault write capability for rotation tasks.

Known gaps in the MCP server (as of 2026-06-20):


8. State Machine / Sequence Diagram

Secret read via MCP server (Option A — proxy)

sequenceDiagram
    actor ML as Main Loop (Claude Code session)
    participant MCP as Infisical MCP Server (npx, localhost)
    participant PX as CF Header Proxy (localhost:2019)
    participant CF as Cloudflare Access gate
    participant IS as Infisical (vault.raxx.app)

    ML->>MCP: get-secret(name="STRIPE_API_KEY", path="/MooseQuest/raptor/prod/")
    MCP->>PX: GET http://localhost:2019/api/v3/secrets/raw/STRIPE_API_KEY
    PX->>PX: inject CF-Access-Client-Id + CF-Access-Client-Secret headers
    PX->>CF: GET https://vault.raxx.app/api/v3/secrets/raw/STRIPE_API_KEY
    CF->>CF: validate CF Access service token
    CF->>IS: forward request + Infisical auth header (short-lived token)
    IS->>IS: RBAC check: identity has read on /MooseQuest/raptor/prod/?
    IS->>IS: write audit log entry (identity, path, timestamp)
    IS-->>CF: 200 { secret_value }
    CF-->>PX: 200 { secret_value }
    PX-->>MCP: 200 { secret_value }
    MCP-->>ML: { name: "STRIPE_API_KEY", value: "<value>" }
    Note over ML: Secret in session context; not written to disk

Machine identity provisioning

sequenceDiagram
    actor OP as Operator
    participant IS as Infisical Admin API
    participant VLT as Infisical (vault.raxx.app)
    participant VLT2 as Velvet Subscription Manifest

    OP->>IS: POST /api/v1/auth/universal-auth/identities (name, scopes)
    IS-->>OP: { client_id, client_secret }
    OP->>VLT: PUT /MooseQuest/identities/<name>/CLIENT_ID  (value: client_id)
    OP->>VLT: PUT /MooseQuest/identities/<name>/CLIENT_SECRET  (value: client_secret)
    OP->>VLT2: add entry to subscription-manifest.yml for rotation
    VLT2-->>OP: identity enrolled in Velvet rotation pipeline
    Note over OP: Distribute CLIENT_ID + CLIENT_SECRET to agent env (Heroku config, GH secret, etc.)

9. The Concrete Spike

Goal: Prove end-to-end that the main loop can call get-secret directly without dispatching sre-agent, using the Infisical MCP server and the recommended access model.

Steps (1–2 hours once the operator selects Option A or B):

Step 1 (15 min): Create a dedicated read-only machine identity in Infisical
  - Name: infisical-identity-mcp-spike-trademaster
  - Scope: project=MooseQuest, env=staging, path=/MooseQuest/spike/, permissions=[read]
  - Store client_id + client_secret in a scratch environment variable (not committed)

Step 2 (15 min): If Option A — stand up the header-injecting proxy locally
  - caddy reverse-proxy --from localhost:2019 --to vault.raxx.app
    with a Caddyfile that injects CF_ACCESS_CLIENT_ID + CF_ACCESS_CLIENT_SECRET headers
  - Alternative: single-file Go or Python proxy (see sub-card SC-VAULT-MCP-01 for implementation)
  - Verify: curl http://localhost:2019/api/v1/auth/universal-auth/login returns 200

Step 3 (10 min): Write a non-secret test value to /MooseQuest/spike/TEST_KEY
  - Value: "spike-hello-2026-06-20" (not a real secret — safe to exist)

Step 4 (15 min): Run the MCP server with spike identity credentials
  - INFISICAL_HOST_URL=http://localhost:2019 (Option A) or https://vault.raxx.app (Option B)
  - INFISICAL_UNIVERSAL_AUTH_CLIENT_ID=<spike client_id>
  - INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET=<spike client_secret>
  - npx -y @infisical/mcp-server

Step 5 (15 min): From Claude Code, call get-secret
  - Tool: get-secret(name="TEST_KEY", projectId=<MooseQuest project ID>, environment="staging", secretPath="/MooseQuest/spike/")
  - Expected: value "spike-hello-2026-06-20" returned directly to session
  - Verify: no sre-agent dispatch; no CF Access header visible to the MCP server

Step 6 (10 min): Negative test — verify RBAC enforcement
  - Attempt get-secret for a path outside /MooseQuest/spike/ (e.g., /MooseQuest/raptor/)
  - Expected: 403 Forbidden from Infisical (RBAC enforcement working)
  - Attempt delete-secret on TEST_KEY
  - Expected: 403 Forbidden (identity has no delete permission)

Step 7 (10 min): Document result in spike card comment; clean up spike identity
  - Delete infisical-identity-mcp-spike-trademaster from Infisical
  - Delete /MooseQuest/spike/TEST_KEY

Spike success criteria: - get-secret returns the correct value in step 5 without sre-agent dispatch. - RBAC enforcement blocks out-of-scope reads in step 6. - No credential values appear in logs.


10. Migrations

No application schema changes. No new Postgres tables.

Infisical config changes (live system): - New machine identities created in Infisical. The existing shared identity is not deleted during the spike; it is deprecated once per-agent identities are provisioned and tested. - New CF Access service token if continuing with Option A (the proxy needs its own CF Access service token, distinct from Velvet's token).

Rollback: Delete the new machine identities. The existing shared identity and CF Access model continue to function. No downtime.


11. Rollout Plan

spike (now)    Provision spike identity → run MCP server → prove get-secret works
               Outcome: operator decision on Option A vs B confirmed

dark           Per-agent identity provisioning for main loop + sre-agent
               Proxy deployed (Option A) or CF Access policy updated (Option B)
               Existing shared identity still active; both paths work

flag           Main loop uses MCP server for reads; sre-agent still available as fallback
               Monitor: audit log confirms reads are attributed to per-agent identities

ga             Shared identity deprecated and revoked
               All agents use per-agent identities
               sre-agent dispatch for vault reads retired
               feedback_main_loop_vault_limit rule removed from MEMORY.md

12. Security Considerations

PII collected: Infisical audit logs record the machine identity, secret path, and timestamp. Secret values are not logged by Infisical. If the Claude session ID is correlated to the identity, a log entry could be linked to a user session. Retention: Infisical audit log retention is configurable on the self-hosted instance; set to 90 days to match WAF log policy (ADR-0077, OQ2). DSR: agent-access logs do not contain end-user PII by default; retention period satisfies the documentation requirement.

Stored credentials: Machine identity client_secret values are stored in Infisical itself (bootstrapped by the Velvet identity) and distributed to execution environments as environment variables. They are not stored in application code, committed to git, or written to disk. Satisfies I1.

Breach notification: If a machine identity is compromised, the blast radius is limited to the paths that identity can read. Discovery path: Infisical audit log shows reads from an unexpected IP or at an unexpected time. Response: revoke the identity immediately (Infisical admin API or UI); provision a replacement; notify operator. If the compromised identity had access to secrets that could affect customer data, GDPR 72-hour breach notification applies.

Kill-switch for live execution: The Infisical MCP server is a session-scoped process (not a persistent daemon). Kill-switch: do not start it. Vault access falls back to the existing sre-agent dispatch model. For persistent services (Raptor, Velvet), their machine identity can be revoked in Infisical in under 60 seconds.

Secrets rotation: Every machine identity is enrolled in the Velvet subscription manifest. Rotation follows the Velvet v2 operational flow. No manual rotation required for the steady state.

Does any part of this store a credential in a form that can be replayed? The proxy (Option A) holds the CF Access service token as an environment variable — same as the existing model. The MCP server holds the Infisical client secret for the duration of the session. Neither is written to disk. No regression from the existing model.


13. Open Questions

These require operator decisions before sub-cards can be claimed.

# Question Blocks Urgency
OQ1 Option A vs Option B? Keep CF Access gate (proxy shim needed) or rely on Infisical native auth + WAF? This is the single decision that determines the spike's implementation path. SC-VAULT-MCP-01 (proxy, if Option A) + all spike steps Blocks spike start
OQ2 Infisical audit log export. Should Infisical audit events be exported to the append-only audit chain (ADR-0022) now, or deferred to a follow-on card after the spike? SC-VAULT-AUDIT-01 Does not block spike
OQ3 Proxy implementation language. If Option A: single-file Python (no new dep, already running on agent workstations) vs Caddy sidecar (zero-code, single binary) vs Go micro-proxy? This is Tier 2 by default (no latency or memory-safety criteria; vault reads are not on the hot path). SC-VAULT-MCP-01 Blocks Option A implementation
OQ4 IP allowlisting posture. Should machine identities for GH Actions runners be IP-allowlisted to GitHub's published Actions runner IP ranges (adds protection, requires updates when GitHub changes ranges) or left unrestricted (simpler, RBAC is the only control)? SC-VAULT-IDENTITY-01 Does not block spike
OQ5 MCP server version pin. The MCP server is young. Pin to a specific npm version in production use (@infisical/mcp-server@x.y.z)? Operator preference: tight pin (stability) vs @latest (auto-updates)? SC-VAULT-MCP-01 Does not block spike