Continuous Non-Human Identity (NHI) verification

Non-Human Identities (NHIs) — service accounts, AI agents, MCP tool clients, CI/CD runners — often receive long-lived credentials with no continuous re-validation. Control Core verifies NHI context on every request at the Bouncer and surfaces them in Agent Access Controls for operators to profile and govern.

Control Core is not an identity directory. Credential lifecycle, enrollment, and secret rotation stay with your existing IAM or NHI management systems. Any vendor can push attributes through a single generic PIP API.

What gets verified

SignalSourceControl use
input.subject.nhi.idSPIFFE ID (XFCC), JWT sub / client_id / azp, or x-cc-agent-idPortable subject key
input.subject.nhi.sourceResolution trust tier: spiffe | jwt | headerWeight enforcement by trust
input.subject.nhi.identity_type_hintDerived from resolution pathClassify workload class
data.pip.nhi_attributes[subject_key]Control Plane NHI registry + POST /v1/pip/subject-attributesPrivilege score, scopes, status

Lifecycle in Agent Access Controls

StatusMeaning
observedFirst seen in Bouncer traffic — Discovery Inbox
profiledOperator set identity type, scopes, privilege score
governedAccess control bound; Rego templates enforce

Open Observe → Agent Access Controls (/observe/nhi) in the Control Plane.

How to use

  1. Deploy a Bouncer on agent/API paths (deployment modes) (~15 min).
  2. Allow traffic — first-seen NHIs auto-register as observed (disable with NHI_AUTO_DISCOVERY=false if needed).
  3. Profile NHIs — set identity type, declared scopes, privilege score; mark profiled or governed.
  4. Optional — sync from your IAM / NHI directory — any system posts portable attributes (no vendor SDK):
curl -sS -X POST "$CONTROL_PLANE/v1/pip/subject-attributes" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "subject_key": "spiffe://example.internal/ns/prod/sa/billing-agent",
    "attributes": [
      {"name": "privilege_score", "value": 3},
      {"name": "identity_type", "value": "orchestrator_agent"},
      {"name": "declared_scopes", "value": ["read:invoices", "tools/read"]}
    ]
  }'
  1. Enable NHI templatesNHI continuous verification, NHI privilege scope, NHI identity type gate under Controls → Templates → AI Security.
  2. Optional M2M tokensPOST /auth/nhi-token with grant_type=client_credentials issues a short-lived JWT (subject_type=nhi) for registered NHIs.

Example Rego (shipped templates read PIP data):

nhi_id := object.get(object.get(input.subject, "nhi", {}), "id", "")
nhi_attrs := object.get(data.pip.nhi_attributes, nhi_id, {})

deny if {
  nhi_id != ""
  object.get(nhi_attrs, "token_freshness_ms", 0) > 300000
}

Troubleshooting: Decisions lack input.subject.nhi?

  • Confirm SPIFFE XFCC, JWT with subject_type=nhi / client_id, or x-cc-agent-id is present
  • Check Audit Logs for actor_type=ai_agent
  • Full reference: Troubleshooting

Troubleshooting: PIP attributes missing in Rego?

  • Confirm the NHI attributes data source is healthy (Policy Bridge Completed)
  • Re-save the NHI profile or re-post /v1/pip/subject-attributes
  • See PIP getting started

How to review / audit

  • Agent Access Controls — Discovery Inbox + registry by status
  • Audit Logs — filter agent_id_str / actor_type=ai_agent
  • Grafana dashboard cc-02-nhi-activity when configured (see Grafana dashboards)

Periodic review checklist:

  • New observed NHIs reviewed within your SLA
  • Production NHIs are governed with declared scopes
  • External directory attributes stay in sync via /v1/pip/subject-attributes

Next steps: MCP blast radius · Agent framework connectors · AI governance overview