Skip to content

Agent security model

The tier-3 agent is the trust boundary between RapidValue's control plane and your environment. The threat model assumes the control plane is partially trusted (operated by us) and the agent must protect against both passive interception and an active control-plane compromise.

Trust boundaries

┌────────────────────────────────┐         ┌──────────────────────────────┐
│  RapidValue control plane      │  HTTPS  │  Your VPC                    │
│  (cloud, multi-tenant)         │  ───→   │  ┌────────────────────────┐  │
│                                │  ←───   │  │  tier3_agent.py        │  │
│  - issues task envelopes       │ long-   │  │  - local vault         │  │
│  - never sees credentials      │ poll    │  │  - HMAC key            │  │
│  - never sees identity records │         │  │  - optional mTLS cert  │  │
└────────────────────────────────┘         │  └────────────┬───────────┘  │
                                           │               │              │
                                           │               ↓              │
                                           │  Targets: LDAP, SAP, Entra,  │
                                           │  internal REST APIs, …       │
                                           └──────────────────────────────┘

Network

  • Outbound HTTPS only. Agent initiates the connection. No inbound ports need to be opened in your firewall.
  • Long-poll, not WebSocket. Survives proxies, NAT timeouts, and corporate egress filters. ~30s poll interval, configurable.
  • TLS 1.2+ enforced. Agent refuses to start if it can't negotiate.

Secret handling

Rule: secrets never travel from the control plane to the agent.

  • The control plane stores only vault references like vault://local/salesforce-prod/client_secret/v3.
  • When a task envelope arrives, it carries the reference, not the value.
  • The agent resolves the reference against its local vault (a JSON file at RV_AGENT_VAULT_PATH by default /opt/rapidvalue/agent-vault.json).
  • The agent calls the target with the resolved credential.
  • Response payloads going back to the control plane go through a _redact() pass that strips known auth headers.

A control-plane compromise cannot exfiltrate target credentials — they were never there.

Self-update verification

Per-agent HMAC signing key (RV_AGENT_UPDATE_KEY) issued at registration and never re-transmitted.

When the control plane offers a new agent binary:

  1. Control plane signs the binary bytes with the agent's key.
  2. Agent receives (payload, signature).
  3. Agent computes HMAC over payload with its local key.
  4. Agent calls hmac.compare_digest() for timing-safe compare.
  5. On mismatch: log + alert, do not apply.

Crash-loop rollback

If a self-update applies but the new binary crashes during boot:

  1. Pre-update, agent writes current tier3_agent.pytier3_agent.py.bak.
  2. Post-update, agent starts. Waits 60 seconds of healthy operation, then touches tier3_agent.py.stable.
  3. On next start, if .bak exists but .stable is missing → assumes the previous boot crashed → reverts to .bak, reports the failure to the control plane.

You get auto-recovery without leaving a broken agent in the field.

Optional mTLS

For an additional spine-auth factor beyond the bearer token:

  1. Generate (or use existing PKI) a client cert pair on the agent host.
  2. Register the SHA-256 fingerprint in the tenant.
  3. Configure the agent to present the cert on outbound calls.
  4. Configure your load balancer (the one in front of the control plane) to validate the cert and pass X-Client-Cert-Fingerprint to the backend.
  5. The control plane's AgentMtlsMiddleware checks the fingerprint against the registered value. Mismatch → 403.

mTLS is optional — bearer-token auth is the baseline. mTLS is recommended for environments where the LB chain is fully under your control.

Audit logging

Every agent operation is logged to audit_event:

  • agent.task_claimed — task ID, method, connector
  • agent.task_completed / agent.task_failed — duration, result size, error class
  • agent.self_update_applied / agent.self_update_reverted
  • agent.registered / agent.disabled

These are queryable in the tenant's Audit log view and exported in the take-home POC report.

What an attacker with control of the control plane cannot do

  • Exfiltrate target credentials. They live in the agent's local vault, never traversed.
  • Inject arbitrary code without HMAC. Self-update requires a valid signature with the per-agent key, which the agent never re-transmits.
  • Impersonate an agent. Bearer token + optional mTLS fingerprint bind agent identity.
  • See bulk identity data. Yes — they would see results streamed back. This is inherent to the architecture: the control plane needs the data to do governance. The mitigation is not at the agent layer — it's at the tenant operator's contractual + technical relationship with RapidValue (SOC 2 + EU-residency commitments).

What this design cannot protect against

  • A compromised agent host (root access). The local vault is plaintext by design — wrap it with disk encryption + OS-level access control if threat-model demands it.
  • A malicious insider with access to both the agent host and the control plane.
  • Side-channel attacks on the agent process from co-tenanted workloads on the same VM. Recommendation: run the agent on a dedicated host or in an isolated container.

RapidValue IGA · Built in Belgium