Governance
29 operations. {prefix} is the route prefix passed to
MapAgentPrism; the template uses /agentprism.
GET {prefix}/api/approvals/rules
Section titled “GET {prefix}/api/approvals/rules”Operation ID: AgentPrismListApprovalRules
Lists persistent ‘don’t ask again’ approval rules.
Each rule pre-approves a tool call so it never reaches the approval mailbox again, which makes this list a standing grant worth reviewing. A rule with no agent name applies to every agent in the tenant. When it carries an arguments hash the rule matches only that exact call; without one it matches every call to that tool. Rules do not expire — remove one to start asking again.
Authorization: bearer authentication; Admin role policy when that policy is registered; RunsRead API-key scope.
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → array of ToolApprovalRule |
— |
POST {prefix}/api/approvals/rules
Section titled “POST {prefix}/api/approvals/rules”Operation ID: AgentPrismCreateApprovalRule
Creates a persistent, argument-conditioned approval rule.
Writes a standing ‘don’t ask again’ rule with an admin-authored comparison (for example “amount <= 100”), evaluated on every call. There is no free-text expression field: the operator is a closed set and conditions combine with AND only. A code-defined policy (IAgentPrismBuilder.AddToolApprovalPolicy) always runs first and can override this rule in both directions.
Authorization: bearer authentication; Admin role policy when that policy is registered; SecurityAdmin API-key scope.
Request body (required):
application/json→ToolApprovalRuleRequest
| Response | Body | Headers |
|---|---|---|
| 201 Created | application/json → ToolApprovalRule |
— |
DELETE {prefix}/api/approvals/rules/{ruleId}
Section titled “DELETE {prefix}/api/approvals/rules/{ruleId}”Operation ID: AgentPrismDeleteApprovalRule
Revokes a persistent approval rule.
After the rule is deleted, approval is asked again for that tool.
Authorization: bearer authentication; Admin role policy when that policy is registered; RunsWrite API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
ruleId |
path | yes | string (uuid) |
— |
| Response | Body | Headers |
|---|---|---|
| 204 No Content | — | — |
GET {prefix}/api/audit
Section titled “GET {prefix}/api/audit”Operation ID: AgentPrismListAudit
Lists audit entries, filterable by actor, action, entity, and date range.
Filterable by actor, action, entity, and date range. Runs (an agent processing a message) are not written to this log; the runs table already keeps the full record. The one exception is the ‘content.blocked’ action: an IContentGuard’s block decision is a GOVERNANCE decision, not a run detail, and must remain traceable even after the run record is deleted by retention policy. The entry carries only the guard and rule name, never the blocked TEXT.
Authorization: bearer authentication; Admin role policy when that policy is registered; AuditRead API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
actor |
query | no | string |
— |
action |
query | no | string |
— |
entity |
query | no | string |
— |
after |
query | no | string (date-time) |
— |
before |
query | no | string (date-time) |
— |
limit |
query | no | integer (int32) |
pattern `^-?(?:0\ |
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → array of AuditEntry |
— |
GET {prefix}/api/audit/{entity}
Section titled “GET {prefix}/api/audit/{entity}”Operation ID: AgentPrismGetEntityAudit
Returns a single entity’s change history, newest first.
The path segment is the full entity key as it was recorded, in the form ‘
Authorization: bearer authentication; Admin role policy when that policy is registered; AuditRead API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
entity |
path | yes | string |
— |
limit |
query | no | integer (int32) |
pattern `^-?(?:0\ |
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → array of AuditEntry |
— |
GET {prefix}/api/audit/verify
Section titled “GET {prefix}/api/audit/verify”Operation ID: AgentPrismVerifyAuditChain
Walks the tenant’s audit trail hash chain and reports whether it is intact.
‘Valid’ means every entry’s hash matches its content and links to the one before it. ‘Broken’ means an entry’s stored hash no longer matches its content — it was altered after it was written. ‘Gap’ means a link between two entries is missing — a row was deleted, or a write never completed; ‘firstFailingEntryId’ names where. An entry written before this feature shipped carries no hash and is excluded from the walk, not misreported as broken. Without ‘?after=’/‘?before=’ the whole tenant history is walked; a narrower range is cheaper but cannot judge a break exactly at its own edge, because the entry just before the range is not read.
Authorization: bearer authentication; Admin role policy when that policy is registered; AuditRead API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
after |
query | no | string (date-time) |
— |
before |
query | no | string (date-time) |
— |
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → AuditChainVerification |
— |
DELETE {prefix}/api/data-subjects/{id}
Section titled “DELETE {prefix}/api/data-subjects/{id}”Operation ID: AgentPrismEraseDataSubject
Deletes a data subject’s content.
‘{id}’ is resolved through IDataSubjectResolver; without one this returns 409, never a silent no-op that could be read as ‘already erased’. ‘?dryRun=’ DEFAULTS TO TRUE: a bare call previews the row counts and deletes nothing; ‘?dryRun=false’ deletes for real. The audit trail (audit_log) is never touched — it is deliberately outside a data subject’s erasable content (by design: an audit record is ‘who did what’, not the subject’s own data) — but the erasure ITSELF is written there, with the row count per target; if that write fails, every delete is rolled back and this call fails, the same rule Approval decisions follow.
Authorization: bearer authentication; Admin role policy when that policy is registered; SecurityAdmin API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
id |
path | yes | string |
— |
dryRun |
query | no | boolean |
— |
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → DataSubjectErasureResult |
— |
GET {prefix}/api/data-subjects/{id}/export
Section titled “GET {prefix}/api/data-subjects/{id}/export”Operation ID: AgentPrismExportDataSubject
Exports a data subject’s content as one JSON document.
‘{id}’ is resolved through IDataSubjectResolver, which is registered by the consumer — AgentPrism does not store personal identity. Without a registered resolver this returns 409, never an empty document. The document holds every column of every matching row, keyed by target table (session state, runs, run inputs, attachment METADATA only — no file bytes, voice session summaries, run scores, conversations, conversation items, and responses); a target with no matching rows is present as an empty array, not omitted.
Authorization: bearer authentication; Admin role policy when that policy is registered; SecurityAdmin API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
id |
path | yes | string |
— |
| Response | Body | Headers |
|---|---|---|
| 200 OK | — | — |
GET {prefix}/api/mcp-servers
Section titled “GET {prefix}/api/mcp-servers”Operation ID: AgentPrismListMcpServers
Lists registered remote MCP servers.
The response CARRIES NO SECRETS: the authentication value is not stored; only the name of the configuration key from which the value will be read is returned.
Authorization: bearer authentication; Reader role policy when that policy is registered; AgentsRead API-key scope.
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → array of McpServerDefinition |
— |
PUT {prefix}/api/mcp-servers/{name}
Section titled “PUT {prefix}/api/mcp-servers/{name}”Operation ID: AgentPrismSaveMcpServer
Adds or updates a remote MCP server.
SECURITY BOUNDARY. Adding an MCP server means accepting tool definitions from an external source. Only http/https addresses are accepted; local process (stdio) transport is not supported. Tools require approval by default.
Authorization: bearer authentication; Admin role policy when that policy is registered; AgentsAdmin API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
name |
path | yes | string |
— |
Request body (required):
application/json→McpServerRequest
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → McpServerDefinition |
— |
DELETE {prefix}/api/mcp-servers/{name}
Section titled “DELETE {prefix}/api/mcp-servers/{name}”Operation ID: AgentPrismDeleteMcpServer
Deletes a remote MCP server.
The registration is removed, so the tools it contributed stop being offered to agents. Agent definitions that name those tools are not rewritten and will fail validation on their next save — check which agents use the server before removing it. No request is made to the remote server itself. An unknown name returns 404.
Authorization: bearer authentication; Admin role policy when that policy is registered; AgentsAdmin API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
name |
path | yes | string |
— |
| Response | Body | Headers |
|---|---|---|
| 204 No Content | — | — |
GET {prefix}/api/mcp-servers/{name}/oauth/callback
Section titled “GET {prefix}/api/mcp-servers/{name}/oauth/callback”Operation ID: AgentPrismMcpOAuthCallback
Processes the OAuth provider’s callback request.
This endpoint is outside the access layers: the browser redirected by the provider cannot carry our bearer token. Security relies on the single-use ‘state’ value.
Authorization: anonymous.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
name |
path | yes | string |
— |
code |
query | no | string |
— |
state |
query | no | string |
— |
iss |
query | no | string |
— |
error |
query | no | string |
— |
| Response | Body | Headers |
|---|---|---|
| 200 OK | — | — |
POST {prefix}/api/mcp-servers/{name}/oauth/start
Section titled “POST {prefix}/api/mcp-servers/{name}/oauth/start”Operation ID: AgentPrismStartMcpOAuth
Starts the OAuth authorization flow for an MCP server.
The administrator is redirected to the returned ‘authorizationUri’. After approval, the provider redirects back to the ‘/oauth/callback’ endpoint; that endpoint uses the ‘state’ value for CSRF protection.
Authorization: bearer authentication; Admin role policy when that policy is registered; SecurityAdmin API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
name |
path | yes | string |
— |
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → McpOAuthStartResponse |
— |
GET {prefix}/api/mcp-servers/{name}/prompts
Section titled “GET {prefix}/api/mcp-servers/{name}/prompts”Operation ID: AgentPrismListMcpPrompts
Gets an MCP server’s prompt list.
If the server does not advertise the ‘prompts’ capability, the request is never sent.
Authorization: bearer authentication; Admin role policy when that policy is registered; AgentsRead API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
name |
path | yes | string |
— |
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → array of McpPromptSummary |
— |
POST {prefix}/api/mcp-servers/{name}/prompts/{prompt}
Section titled “POST {prefix}/api/mcp-servers/{name}/prompts/{prompt}”Operation ID: AgentPrismGetMcpPrompt
Resolves an MCP prompt’s content with arguments.
The returned content is a SNAPSHOT: it must be copied into the agent’s instructions; it is not re-fetched at runtime. The ‘hash’ field is for tracking changes on the server.
Authorization: bearer authentication; Admin role policy when that policy is registered; AgentsRead API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
name |
path | yes | string |
— |
prompt |
path | yes | string |
— |
Request body (optional):
application/json→McpPromptArgumentsRequest
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → McpPromptContent |
— |
GET {prefix}/api/mcp-servers/{name}/resources
Section titled “GET {prefix}/api/mcp-servers/{name}/resources”Operation ID: AgentPrismListMcpResources
Gets an MCP server’s resource list.
If the server does not advertise the ‘resources’ capability, the request is never sent.
Authorization: bearer authentication; Reader role policy when that policy is registered; AgentsRead API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
name |
path | yes | string |
— |
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → array of McpResourceSummary |
— |
GET {prefix}/api/mcp-servers/{name}/resources/read
Section titled “GET {prefix}/api/mcp-servers/{name}/resources/read”Operation ID: AgentPrismReadMcpResource
Reads an MCP resource.
Only URIs advertised by the server’s ListResourcesAsync are accepted; an arbitrary URI is rejected because it carries an SSRF risk.
Authorization: bearer authentication; Operator role policy when that policy is registered; AgentsRead API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
name |
path | yes | string |
— |
uri |
query | yes | string |
— |
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → McpResourceContent |
— |
POST {prefix}/api/mcp-servers/refresh
Section titled “POST {prefix}/api/mcp-servers/refresh”Operation ID: AgentPrismRefreshMcpTools
Refreshes the tool list of remote MCP servers now.
The refresh normally happens in the background at fixed intervals. This endpoint lets the tools of a newly added server appear without waiting for the next scheduled refresh.
Authorization: bearer authentication; Admin role policy when that policy is registered; AgentsAdmin API-key scope.
Request body (optional):
application/json→nulloneOfIMcpToolRefresher
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → McpRefreshResponse |
— |
GET {prefix}/api/quotas
Section titled “GET {prefix}/api/quotas”Operation ID: AgentPrismListQuotas
Lists a tenant’s quota rules.
Rules are definitions, not counters — read the counters from the usage endpoint. A rule with no agent name applies to the whole tenant, and a tenant-wide rule and an agent-specific rule can both be in force at once. A rule with ‘enabled: false’ is kept but not enforced. An agent with no matching rule is unlimited.
Authorization: bearer authentication; Admin role policy when that policy is registered; PlatformRead API-key scope.
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → array of QuotaDefinition |
— |
PUT {prefix}/api/quotas
Section titled “PUT {prefix}/api/quotas”Operation ID: AgentPrismSaveQuota
Creates or updates a quota rule.
The scope (tenant + agent + period) is unique: writing a second rule for the same scope overwrites the existing rule. Each limit can also be left empty; only the ones that are set are enforced.
Authorization: bearer authentication; Admin role policy when that policy is registered; PlatformAdmin API-key scope.
Request body (required):
application/json→QuotaSaveRequest
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → QuotaDefinition |
— |
DELETE {prefix}/api/quotas/{id}
Section titled “DELETE {prefix}/api/quotas/{id}”Operation ID: AgentPrismDeleteQuota
Deletes a quota rule.
Removing the last rule that covers an agent makes it unlimited, which is why the removal is written to the audit trail with the rule’s previous values. Usage counters already recorded are not deleted; they simply stop being enforced. To keep the limits but stop enforcing them, save the rule with ‘enabled: false’ instead. An unknown id returns 404.
Authorization: bearer authentication; Admin role policy when that policy is registered; PlatformAdmin API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
id |
path | yes | string (uuid) |
— |
| Response | Body | Headers |
|---|---|---|
| 204 No Content | — | — |
GET {prefix}/api/quotas/usage
Section titled “GET {prefix}/api/quotas/usage”Operation ID: AgentPrismGetQuotaUsage
Returns the current period’s quota usage.
An empty ‘agentName’ value shows the tenant-wide counter. Counters are approximate: the check happens before a run starts, and consumption is written after it finishes.
Authorization: bearer authentication; Reader role policy when that policy is registered; PlatformRead API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
agentName |
query | no | string |
— |
period |
query | no | QuotaPeriod |
— |
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → QuotaUsageResponse |
— |
GET {prefix}/api/skill-script-grants
Section titled “GET {prefix}/api/skill-script-grants”Operation ID: AgentPrismListSkillScriptGrants
Lists the tenant’s script run grants.
A grant is permission to execute code on the server, so this list is the authoritative answer to ‘what may run here’. A grant with no script name covers every script in that skill; one with a script name covers only that script. Entries may carry an expiry, and an expired grant no longer authorizes a run. Grants are also a retention target, so old ones are cleaned up.
Authorization: bearer authentication; Reader role policy when that policy is registered; SecurityAdmin API-key scope.
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → array of SkillScriptGrant |
— |
POST {prefix}/api/skill-script-grants
Section titled “POST {prefix}/api/skill-script-grants”Operation ID: AgentPrismGrantSkillScript
Grants run permission to a skill script.
Granting while script execution is switched off returns 409 rather than succeeding: a grant that reads as active but never allows a run would be misleading. Omit ‘scriptName’ to cover every script in the skill. ‘expiresAt’ is optional but must be in the future when given (400 otherwise); without it the grant does not expire. Every change is written to the audit trail.
Authorization: bearer authentication; Admin role policy when that policy is registered; SecurityAdmin API-key scope.
Request body (required):
application/json→SkillScriptGrantRequest
| Response | Body | Headers |
|---|---|---|
| 201 Created | application/json → SkillScriptGrant |
— |
DELETE {prefix}/api/skill-script-grants/{skillName}
Section titled “DELETE {prefix}/api/skill-script-grants/{skillName}”Operation ID: AgentPrismRevokeSkillScript
Revokes a script run grant.
Revoking takes effect on the next run; a script already executing is not stopped. The optional ‘?scriptName=’ must match how the grant was created — revoking one script does not remove a skill-wide grant, and the skill-wide grant keeps authorizing that script until it too is revoked. When no matching active grant exists the response is 404.
Authorization: bearer authentication; Admin role policy when that policy is registered; SecurityAdmin API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
skillName |
path | yes | string |
— |
scriptName |
query | no | string |
— |
| Response | Body | Headers |
|---|---|---|
| 204 No Content | — | — |
GET {prefix}/api/tenants
Section titled “GET {prefix}/api/tenants”Operation ID: AgentPrismListTenants
Lists registered tenants.
A tenant record is NOT REQUIRED. The tenant_id in other tables is the same text as this record’s slug value, but it is not connected by a foreign key; a tenant with no record does not produce an error at runtime.
Authorization: bearer authentication; Admin role policy when that policy is registered; PlatformAdmin API-key scope.
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → array of TenantDescriptor |
— |
PUT {prefix}/api/tenants/{slug}
Section titled “PUT {prefix}/api/tenants/{slug}”Operation ID: AgentPrismSaveTenant
Adds or updates a tenant record.
The record is a display name for a tenant key that already works without it; creating one does not create the tenant and deleting one does not remove its data. The slug comes from the path and must be at most 64 characters of letters, digits, dots, underscores, and hyphens (400 otherwise) — it is the same text stored as ‘tenant_id’ on every other row. An empty display name falls back to the slug.
Authorization: bearer authentication; Admin role policy when that policy is registered; PlatformAdmin API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
slug |
path | yes | string |
— |
Request body (required):
application/json→TenantRequest
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → TenantDescriptor |
— |
DELETE {prefix}/api/tenants/{slug}
Section titled “DELETE {prefix}/api/tenants/{slug}”Operation ID: AgentPrismDeleteTenant
Deletes a tenant record.
Only the record is deleted; the tenant’s agents, sessions, and runs remain.
Authorization: bearer authentication; Admin role policy when that policy is registered; PlatformAdmin API-key scope.
| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
slug |
path | yes | string |
— |
| Response | Body | Headers |
|---|---|---|
| 204 No Content | — | — |
GET {prefix}/api/tenants/current
Section titled “GET {prefix}/api/tenants/current”Operation ID: AgentPrismCurrentTenant
Returns the current request’s tenant.
The tenant is resolved from the request. In a single-tenant setup, it always returns the default tenant. This endpoint is in the protected group; /api/meta does not carry tenant information.
Authorization: bearer authentication; Reader role policy when that policy is registered; no endpoint-specific API-key scope.
| Response | Body | Headers |
|---|---|---|
| 200 OK | application/json → CurrentTenantResponse |
— |