Governing AI agents
An AI agent is not a new kind of object in this platform. It is an identity — one that happens to act without a person at the keyboard — governed by the same ownership, attestation and access machinery as every other non-human identity.
The boundary first: what is governed here is the identity an agent uses, not the agent's behaviour. Nothing here stops a program from running; it decides whether the identity that program authenticates as is known, owned, current and revocable. The calls an agent makes through RapidValue's MCP gateway are decided one by one, and that is described in Deciding every agent call. Agents that people connected on their own are found through Shadow AI agents.
What makes an agent an agent
An agent is an identity of type ai_agent, so every non-human control already
applies: ownership resolution, the orphan inbox, blast-radius, emergency lockout,
reconciliation. On top of it sits a one-to-one agent profile carrying what
only makes sense for an agent — a purpose in prose, an autonomy tier (how
much human oversight sits between the agent and each act), the platform it lives
on and its identifier there, and optionally the person or team it acts for.
Separately, the identity carries a lifecycle driver: the asserted reason the non-human identity exists. That answers a different question. The autonomy tier describes declared human oversight; the lifecycle driver determines how the NHI should be treated across its lifetime. Neither is inferred from runtime behaviour.
That last field is the clearest difference from a service account: a service account runs a job, an agent acts on someone's behalf, and the model records whose. Purpose, latitude and named principal are three facts a service account has no field for.
A person's AI assistant is an agent too. Every OAuth client a person signs
into RapidValue with, on RapidValue's own MCP endpoint and at the gateway, is
its own ai_agent identity, created when the client is registered and owned by
the administrator who registered it unless another owner is named. The person
stays the ceiling: the assistant never gets a right of its own on RapidValue's
endpoint, and at the gateway both the assistant and the person must be entitled.
Every call names both. Because the assistant is an identity, its kill switch,
lockout or retirement refuses its next request, token refresh and authorization;
a person's client is a public client with no secret, so the stop is that per-use
refusal. The database refuses an active person's client without its agent
identity, so no assistant runs ungoverned.
Provenance is enforced, not decorative
Every agent record says where it came from, and that field cannot be talked into saying something else. Discovered means a platform sync actually saw the object. These platforms are read today:
| Platform | What is discovered |
|---|---|
| Microsoft Entra | Agent ID agent identities |
| AWS | Amazon Bedrock agents, Bedrock AgentCore runtimes (the runtime's owner tag is the sponsor), and IAM users you declare as agents with the rv:ai-agent tag |
| Google Cloud | Vertex AI Agent Engine deployments, Agentspace agents, and service accounts you declare as agents in the connector configuration |
| Salesforce | Agentforce agents from BotDefinition, limited to the API names you list, because the same object also holds classic Einstein Bots |
| ServiceNow | AI agents from sn_aia_agent; switching the object on is the declaration |
| GitHub | App installations you list as agents; off by default because it needs the admin:read scope |
| Claude (Anthropic) | Managed agents per workspace, with their tools, MCP servers and skills, and the sponsor only where the agent's metadata names an owner; off by default |
| OpenAI | No agent object. The connector reads the organisation's people, projects and service accounts, and project API keys as credentials |
The AgentCore, Agentspace, Salesforce and ServiceNow objects are off by default.
The Claude and OpenAI connectors are read-only: they sign in with an organisation Admin API
key and may only send reads to a fixed list of paths, so a write cannot leave them. Claude
has no read-only Admin key, and its connection test says so; for OpenAI the setup guide asks
for a key with the Read only permission. On
Claude an Admin key cannot read service accounts; the connection test names that and the
connector works without them. A service account the platform does report becomes a
service account identity, keyed on the platform's own id, so the keys it holds are attached
to it and an owner can be proposed from who created them. On OpenAI this happens with the
ordinary sync; on Claude the service-account object is off by default, because only an OAuth
admin token can read it. The platform's enabled flag moves the identity between active and
terminated; a kill-switch suspension or a retirement is left as it is. Several Salesforce, ServiceNow, Claude and OpenAI field names
have not yet been proven against a live org, so they sit behind the declaration and an editable field list; a read
that fails is reported as incomplete, never as "no agents". Each record becomes an
ai_agent identity, marked discovered and stamped with the platform's own
identifier. Discovery rides the sync
that already runs rather than being a separate action. Nothing is inferred from a
name: on AWS, Google Cloud and GitHub a user, service account or app counts as an
agent only because you declared it. Registered means a human declared it: the intake path for a
self-hosted agent no platform can see, honest about being a declaration.
The two cannot be conflated. A profile's editable surface is exactly three fields — purpose, autonomy tier and the acts-for link. The agent's owner can edit its purpose; the autonomy tier and the acts-for link stay with an administrator, and a change from the owner that touches them is refused. An attempt to set the source, the platform or the external identifier is rejected outright rather than quietly dropped, because a declared agent rendering as "discovered" would turn an assertion into evidence. The rule runs the other way too: a later sync refreshes provenance only. It will fill an empty purpose, but never overwrites a purpose, tier or acts-for link a human asserted — upstream config changes for reasons that have nothing to do with who accepted accountability here.
The register at a glance
An administrator adds a platform from the register with Connect an AI platform, which opens the system picker on its AI platforms group. Microsoft Entra, AWS and Google Cloud are listed there too, marked as part of that system, because their agents are read through that system's own connector.
The agent register opens on a posture row: how many agents each platform holds, the open Advisor findings that name an agent, and how many agent calls RapidValue decided in the last 30 days. Each row shows the agent's platform and its open findings, with the most severe named, and, where runtime decisions are set up, whether its calls were observed, enforced or both. The list filters on platform and on a kind of finding, and a finding that names several agents shows on each of their rows. Source and credentials are extra columns you can switch on.
Two or more agents on one system that run as the same AWS role (a Bedrock service role or an AgentCore execution role) or the same Google Cloud service account raise one finding for the system's owner: a kill or a narrowed permission on that principal reaches every agent on it. The finding has no fix button, because only the platform can give an agent its own principal. Entra agent identities that share a blueprint are not flagged; that is how Entra is built.
Permissions on the platform
An agent also holds access on the platform it lives on, and that is often where its reach is. For agents imported from Entra, AWS and Google Cloud, discovery reads it with the agent record: on Entra the app roles, delegated grants and directory role or group memberships of each agent identity; on AWS the managed and inline policy names of the agent's role or user (and a user's groups); on Google Cloud the project roles bound to the agent's principal and an Agentspace agent's authorizations. The agent's page shows them under "Permissions on the platform", with the time of the last complete read per system. A read that did not finish keeps the last complete list and says why, rather than showing an empty one.
A Claude managed agent's tools, MCP servers and skills land as permissions of their own kind, so the register tells a shell tool from an MCP server. An agent connected to an MCP server that no listing in RapidValue's MCP catalogue covers raises one Advisor finding per system and server address, naming every agent on it, for the system's owner. The address is compared without case, default port, trailing slash, query or fragment; a server's display name is not used. The finding has no fix button: the fix is listing the server with an owner, or removing it on the platform. MCP servers of Entra and Google Cloud agents are not checked this way.
Ownership: filled from the sponsor, never overwritten
Where the platform carries a sponsor or owner tag — the human it holds accountable for the agent — discovery imports that as the agent's owner, fill-only: one explicit ownership record, written only when no owner exists yet. An owner a human set is never replaced by a later sync, and an agent whose sponsor is unreadable or ambiguous gets no owner row at all; it surfaces as unowned and flows into the normal claim process. That last part is load-bearing: a placeholder owner would raise ownership coverage without raising accountability, and coverage that counts fictions is worse than a visible gap.
The "imported from sponsor" badge on an agent follows the owner it describes: when the owner later changes hands, through a handover or a reassignment, the badge is removed instead of standing next to the new owner. A sponsor whose Entra account RapidValue itself provisioned still resolves.
Lifecycle driver: asserted reason for existence
The generic NHI tier ladder was retired. In its place, a lifecycle driver resolves from an explicit assertion, an inherited account-type default, a visible conflict, a non-binding suggestion or unknown. Only an asserted or inherited driver may suppress a driver-specific finding; a suggestion is not evidence.
A runtime-driven identity can therefore be treated differently from a
person-sponsored service identity without pretending that its identity_type
proves why it exists. Unknown and conflicting drivers remain visible.
Autonomy tiers and the attestation ladder
Three autonomy tiers are recorded per agent: assisted (a human in the loop for every act), supervised (the agent acts, a human reviews) and autonomous (the agent acts unattended). The tier is not a badge — it selects how often the agent is re-confirmed, through seeded certification rules evaluated in priority order:
| Tier | Re-attested every |
|---|---|
| Autonomous | 90 days |
| Supervised | 180 days |
| Assisted | 365 days |
| Agent with no profile | 365 days |
The less human oversight there is per act, the more often accountability is
re-confirmed. The fourth row is not filler: an ai_agent identity can
legitimately have no profile — a legacy record, or one created outside the intake
path — and without that floor it would fall through into the generic non-human
rule, which sits below all four and covers every other non-human identity yearly.
The same cadence drives two reviews. The attestation asks whether the agent is still needed, still owned and still operating within its declared purpose. The access review puts the agent's grants, runtime permissions included, in front of its owner, with what matters for an agent before keeping or revoking: its purpose, tier, attestation, last activity, the runtime decisions of the last 30 days and the terms it accepted. The owner's revoke ends the access through the normal review revoke, and a review left unanswered revokes at its deadline. A review never routes to the agent itself.
The attestation routes to the agent's owner (with a manager on record only as a labelled fallback, see access reviews), carries a 30-day grace period, and on expiry flags for review rather than revoking anything. The agent's review card tells the states apart: Not attested yet for an agent that was never attested, "Attestation ran out on" a date when the last one lapsed and no new cycle is open, and "Attested until" only inside a valid attestation.
Credential inventory: references, kinds and dates
The inventory answers "what does this agent hold, and when does it stop working" — the commonest cause of an agent failing in production being a client secret nobody rotated. It holds a reference (the credential's identifier at the source), its kind and its dates, and no secret material at all: there is no column that could carry any, because a third secret path hiding in an inventory table would be a third place a secret could leak from.
A daily sweep reads it from connectors declaring the capability, today Microsoft Entra (application-registration secrets and certificates, attached to every agent built on the same blueprint), AWS (access keys of agent IAM users, and AgentCore token-vault providers tagged with the runtime they belong to), Google Cloud (user-managed service-account keys), Google Workspace (application-specific passwords), Salesforce (the OAuth tokens of agent running users and API-only integration users, by connected app, with their use count) and ServiceNow (the refresh tokens and API keys of integration users, and OAuth application registry entries whose application user is one). Token and secret fields are never in a query's field list. Findings are raised ahead of the date: expired, expiring within the window, rotation overdue (a working credential created at the source more than 90 days ago), and no expiry at all — the last a standing posture finding rather than an imminent outage, since such a credential can never be rotated by a deadline, only by a decision. None of them carries a one-click fix: we do not hold the secret, so the finding points at where rotation happens.
The other absence is treated the same way: an unknown last-use reads "not reported" unless the source itself answers the usage question. AWS does, so a key that never signed a request reads "never used", and so does a credential RapidValue issued. For Entra, Google Cloud and Google Workspace the platform does not tell "never used" from "not reported", so it stays "not reported". Reporting agent sign-in activity from Entra requires Workload ID licensing, and without it the platform has no evidence either way. Activity counts as reported only when a platform-discovered credential arrives carrying a real last-use date — traffic against RapidValue's own API does not count, being our log rather than the target's. Where the evidence is missing the product says so and names the licence requirement, rather than presenting silence as a clean bill of health.
A personal key that looks like automation. On Claude the connector also reads the hourly usage report per API key, which fills the key's last use and lets the platform spot a personal key that runs around the clock: used in at least 20 of 24 hours on at least 5 of the last 7 days, one of them a Saturday or Sunday. Such a key gets a "Looks like automation" chip on the person's Access tab and an Advisor finding for the system's owner that proposes moving it to a service account. Nothing is applied on its own; the finding closes when the key stops matching, and a leaver's key is left to the leaver finding. A key absent from the report is "not reported", not "never used", and a refused usage read leaves the inventory as it was. OpenAI keys carry no usage evidence yet.
The kill-switch composes; the release is deliberately asymmetric
When an agent misbehaves, one action stops the identity it uses — and it is not a new mechanism. It composes the existing emergency lockout, which suspends the identity, force-revokes every grant and disables every account across all connected systems, overriding each connector's normal drift policy; and it revokes the credentials RapidValue issued to that agent. A locked-out agent also stops working on every credential surface: API keys, OAuth token issuance and MCP requests all refuse a credential whose agent is not active.
A discovered agent is an account on the system that found it, so the lockout reaches it there:
| Platform | What the kill does | Release |
|---|---|---|
| Microsoft Entra | Disables the agent identity, then revokes the sign-in sessions of the agent users it owns | Re-enables it |
| AWS | Attaches your deny-all managed policy to the agent's role or IAM user (for an AgentCore runtime, its execution role), then reads it back | Detaches exactly that policy |
| Google Cloud | Disables the agent's own service account, then reads it back | Re-enables it |
| Salesforce, ServiceNow | Not stopped on the platform yet: the agent is locked out of RapidValue and the kill reports that it keeps running there | Lifts the lockout |
| GitHub | Cannot be stopped from RapidValue | Nothing to release |
On Entra, disabling an identity does not end the tokens Entra already issued. Microsoft
Graph can revoke sessions only for users, so the kill revokes the sessions of the agent
users the identity owns; this needs the User.RevokeSessions.All permission, and a
failure is reported separately without undoing the disable. The agent identity's own
app-only tokens cannot be revoked and stay valid until they expire. This path has been
built against the Graph reference and not yet run against a live tenant.
On AWS the kill never writes a policy of its own. You create one managed policy
(RapidValueAgentKillSwitch by default) and the connector may only attach and detach
that one; before attaching it, the connector checks that the policy is exactly
deny-all and in the same account. A connection test that passes on reads but cannot
use the kill policy reports the system as degraded and says so, so a connector that
could not stop an agent does not look ready. Every role assumption carries an external
ID that RapidValue generates per connector and shows read-only; it cannot be typed in.
On Google Cloud an engine that runs on the shared Vertex AI service agent is discovered but not stopped, because disabling that account would stop every engine in the project; the kill says so and names the remedy (deploy the agent with its own service account). An Agentspace agent cannot be stopped from RapidValue at all, and the kill says so and names what to do instead. When a discovered agent keeps running on its platform because RapidValue holds no account there it can stop, the kill reports that in its errors instead of returning a clean result. An agent is never planned a RapidValue personal account, so release does not stall on an account that cannot exist.
A reason is mandatory. The action is recorded as a critical event in the immutable audit log along with what was revoked and, importantly, anything that failed to revoke: partial failures are returned rather than swallowed, because a credential the platform could not revoke is exactly what an incident responder must be told about.
Release lifts the lock and nothing else. The identity becomes active again, accounts are re-enabled, and reconciliation restores the access the Expected state still justifies. The credentials stay revoked. That asymmetry is deliberate rather than a limitation to be fixed: the credential was revoked because it might have leaked, and a possibly-leaked secret should never return as a side effect of someone deciding the incident is over. Reissuing is a second, explicit act, and a reason is mandatory on release too.
Administrators and the security team can both use it — incident response should not wait for an administrator to be found — while releasing it is an administrator action. A lockout is also sent as a Shared Signals (CAEP) event to every subscribed receiver, so a system that validates tokens offline hears of it.
The kill switch is one of five ways to end an agent's access. The others are a revoke in the access review, the end of a mission, the owner withdrawing a terms version, and stopping a person's assistant. All five make the next call fail, because the evaluator reads grants and status live on every call; reconciliation then removes the access at the target. Missions and terms are described in Deciding every agent call.
Evidence
Registration, profile changes, kill-switch activation and release all land in the immutable, hash-chained audit log, and an evidence pack assembles the register, ownership coverage, credential currency, attestation history, each agent's chain and that trail into one verifiable bundle, for the whole tenant or for a single agent (Evidence and signing).
Generated for one agent, the pack is that agent's EU AI Act evidence pack: the terms it accepted and their purposes, its grants with their approvals, the human oversight (requests to the owner, confirmations, reviews), the executions recorded at the gateway, incidents and denials, and logging and retention. An article map says per article what the pack shows and what it does not. It states its own applicability rather than asserting compliance: the EU AI Act articles it cites bind deployers of high-risk AI systems, and identifying which of your agents qualify is your assessment to make, not ours.
Known edges, published rather than discovered
- This governs identities, not behaviour. Nothing here prevents an agent from executing. Autonomy tier and lifecycle driver are declared governance facts, not behavioural detection.
- No behavioural baselines over external agent activity. Anomaly detection built on telemetry we do not own is deliberately not built, and no surface implies it is. What is reported is strictly first-party: a credential we issued reaching for a scope it was not granted (a recorded refusal, not an inference), and a granted scope first used long after issue. Neither resolves itself — "trim the grant", "widen it deliberately" and "we are compromised" are three conclusions from one fact.
- The kill-switch revokes the credentials we issued, not the ones we never hold. A client secret living in Entra is not revoked by RapidValue; the lockout half disables the agent where the platform allows it (see the table above), and the audit record names whatever could not be revoked or reached. GitHub App installations are the clear gap: GitHub gives an organisation owner no way to suspend another vendor's installation.
- Sign-in reporting depends on the source. Where a platform does not report workload sign-in activity, dormancy stays unknown rather than inferred.
- Per-tier cadence is not yet a tenant setting. The four rules are seeded and editable in the certification rule workbench like any other, but there is no dedicated tier-to-cadence control in governance settings.
- Coverage is what the connectors report. Agents on platforms with no connector, and credential kinds outside those named above, are not discovered. Secret stores (Azure Key Vault, HashiCorp Vault) and Kubernetes service accounts are on the roadmap, not built. Agents people connected on their own appear as shadow agents only on Entra and Google Workspace. Google Cloud keys that are not user-managed are not counted as credentials. Registering one by hand is a declaration rather than a discovery, and says so.
Further reading: