Referencia de API REST
Referencia completa de endpoints para la API de gestión de ShieldAgent. URL base: https://api.shieldagent.io (autoalojado: https://api.shieldagent.io)
Autenticación
Todos los endpoints (excepto los marcados como públicos) requieren un token Bearer JWT en el encabezado Authorization. Los tokens se obtienen a través de /auth/login o /auth/signup.
curl https://api.shieldagent.io/tenants \
-H 'Authorization: Bearer <your-jwt>' \
-H 'Content-Type: application/json'Formato de Error
Todas las respuestas de error siguen una estructura JSON consistente. Los errores de validación (400) incluyen detalles a nivel de campo a través de Zod.
{
"error": "Validation failed",
"message": "Invalid request body",
"issues": [
{ "path": ["name"], "message": "Required" },
{ "path": ["riskTier"], "message": "Invalid enum value" }
]
}Paginación
Los endpoints de lista que soportan paginación aceptan parámetros de consulta limit y offset y retornan un objeto pagination:
{
"data": [ ... ],
"pagination": {
"total": 142,
"limit": 50,
"offset": 0,
"hasMore": true
}
}Autenticación
/auth/signupRegister a new tenant and admin user. Returns a JWT.
Rate-limited to 5 requests/minute.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| body | string | yes | User email address | |
| password | body | string | yes | Minimum 8 characters |
| tenantName | body | string | yes | Organization name |
{
"email": "admin@acme.com",
"password": "s3cure-passw0rd",
"tenantName": "Acme Corp"
}{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": { "id": "u_01abc...", "email": "admin@acme.com", "role": "tenant_admin" },
"tenant": { "id": "t_01xyz...", "name": "Acme Corp" }
}/auth/loginAuthenticate with email and password. Returns a JWT.
Rate-limited to 10 requests/minute. Returns 403 with SSORequired error if the account uses SSO.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| body | string | yes | User email address | |
| password | body | string | yes | User password |
{
"email": "admin@acme.com",
"password": "s3cure-passw0rd"
}{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": { "id": "u_01abc...", "email": "admin@acme.com", "role": "tenant_admin" },
"tenant": { "id": "t_01xyz...", "name": "Acme Corp" }
}/auth/meGet the currently authenticated user profile.
{
"id": "u_01abc...",
"email": "admin@acme.com",
"role": "tenant_admin",
"createdAt": "2026-01-15T10:30:00.000Z",
"tenant": { "id": "t_01xyz...", "name": "Acme Corp" }
}/auth/refresh-entitlementsRefresh JWT with current plan tier and entitlements.
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": { "id": "u_01abc...", "email": "admin@acme.com", "role": "tenant_admin" },
"tenant": { "id": "t_01xyz...", "name": "Acme Corp" }
}Tenants
/tenantsCreate a new tenant organization.
tenant:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| name | body | string | yes | Tenant display name |
| planTier | body | string | no | One of: free, team, starter, pro, business, enterprise_cloud, enterprise_onprem. Defaults to free. |
| kmsKeyId | body | string | no | Optional KMS key for envelope encryption |
{
"name": "Acme Corp",
"planTier": "pro"
}{
"id": "t_01xyz...",
"name": "Acme Corp",
"planTier": "pro",
"createdAt": "2026-04-24T12:00:00.000Z"
}/tenantsList tenants. Platform admins see all; others see only their own tenant.
tenant:read[
{
"id": "t_01xyz...",
"name": "Acme Corp",
"planTier": "pro",
"createdAt": "2026-04-24T12:00:00.000Z"
}
]/tenants/:tenantIdGet a single tenant by ID.
tenant:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
/tenants/:tenantIdUpdate tenant fields.
tenant:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| name | body | string | no | Updated tenant name |
| planTier | body | string | no | New plan tier |
| kmsKeyId | body | string | no | Updated KMS key ID |
/tenants/:tenantIdDelete a tenant and all associated data.
tenant:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
{ "deleted": true, "id": "t_01xyz..." }Usuarios
/tenants/:tenantId/usersList users in a tenant with their role assignments.
user:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
[
{
"id": "u_01abc...",
"email": "admin@acme.com",
"role": "tenant_admin",
"active": true,
"createdAt": "2026-01-15T10:30:00.000Z"
}
]/tenants/:tenantId/users/inviteInvite a new user to the tenant.
user:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| body | string | yes | Email address of the user to invite | |
| password | body | string | yes | Initial password (min 8 characters) |
| role | body | string | no | One of: tenant_admin, security_operator, auditor, aiops_engineer, viewer. Default: viewer |
{
"email": "analyst@acme.com",
"password": "init-pass-123",
"role": "security_operator"
}{
"id": "u_02def...",
"email": "analyst@acme.com",
"role": "security_operator",
"active": true,
"createdAt": "2026-04-24T14:00:00.000Z"
}/tenants/:tenantId/users/:userIdUpdate a user's role or active status.
user:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| userId | path | uuid | yes | User UUID |
| role | body | string | no | New role assignment |
| active | body | boolean | no | Set false to deactivate |
/tenants/:tenantId/users/:userIdRemove a user from the tenant. Users cannot delete themselves.
user:delete| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| userId | path | uuid | yes | User UUID |
/rolesList all available roles with their permissions.
[
{
"id": "role_01...",
"name": "security_operator",
"scope": "tenant",
"description": "Can triage incidents, manage alert rules, view audit logs",
"isSystem": true,
"permissions": ["incident:triage", "alert:write", "audit:read"]
}
]Agentes
/tenants/:tenantId/agentsRegister a new AI agent. Returns an agent key for proxy authentication.
agent:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| name | body | string | yes | Agent display name |
| description | body | string | no | Agent purpose description |
| riskTier | body | string | no | Initial risk tier: low, medium, high, critical |
| shadowMode | body | boolean | no | Start in shadow mode (log only, never block). Default: false |
{
"name": "code-assistant",
"description": "GitHub PR review agent",
"riskTier": "medium"
}{
"id": "agt_01HXYZ...",
"name": "code-assistant",
"agentKey": "sa_live_...",
"riskTier": "medium",
"shadowMode": false,
"createdAt": "2026-04-24T12:00:00.000Z"
}/tenants/:tenantId/agentsList all agents in a tenant.
agent:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
/tenants/:tenantId/agents/:agentIdGet a single agent with full configuration.
agent:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| agentId | path | uuid | yes | Agent UUID |
/tenants/:tenantId/agents/:agentIdUpdate agent metadata (name, description, shadowMode, riskTier).
agent:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| agentId | path | uuid | yes | Agent UUID |
| name | body | string | no | Updated agent name |
| description | body | string | no | Updated description |
| shadowMode | body | boolean | no | Toggle shadow mode |
| riskTier | body | string | no | Updated risk tier |
/tenants/:tenantId/agents/:agentIdDeregister an agent and revoke its key.
agent:delete| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| agentId | path | uuid | yes | Agent UUID |
{ "deleted": true, "id": "agt_01HXYZ..." }/tenants/:tenantId/agents/:agentId/rotate-keyRotate the agent's API key. The old key is immediately revoked.
agent:write{
"agentKey": "sa_live_NEW...",
"rotatedAt": "2026-04-24T12:00:00.000Z"
}/tenants/:tenantId/agents/:agentId/security-configConfigure per-agent security detection settings.
agent:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| injectionDetectionEnabled | body | boolean | no | Enable ML injection detection |
| dlpEnabled | body | boolean | no | Enable DLP scanning |
| excessiveAgencyEnabled | body | boolean | no | Enable excessive agency detection |
| toolDriftEnabled | body | boolean | no | Enable tool drift monitoring |
/tenants/:tenantId/agents/:agentId/baseline-configConfigure baseline learning parameters.
agent:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| warmupDays | body | integer | no | Days before drift detection activates (default: 7) |
| sensitivityMultiplier | body | number | no | Drift sensitivity (0.5–3.0, default: 1.0) |
/tenants/:tenantId/agents/:agentId/lockSuspend an agent. All tool calls will be blocked until unlocked.
agent:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| reason | body | string | no | Reason for suspension (written to audit trail) |
/tenants/:tenantId/agents/:agentId/unlockReinstate a suspended agent.
agent:write/tenants/:tenantId/agents/:agentId/baselineReset an agent's behavioral baseline. Drift scoring restarts from zero.
agent:write{ "reset": true, "agentId": "agt_01HXYZ..." }Políticas
/tenants/:tenantId/policiesCreate a policy rule for a tenant, agent, or tool.
policy:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| agentId | body | uuid | no | Scope to a specific agent (omit for tenant-wide) |
| toolName | body | string | yes | Tool pattern to match (supports wildcards) |
| action | body | string | yes | allow, deny, or shadow |
| conditions | body | object | no | Optional condition object (method, path, param matchers) |
| priority | body | integer | no | Evaluation priority (lower = first). Default: 100. |
{
"agentId": "agt_01HXYZ...",
"toolName": "rest:stripe",
"action": "deny",
"conditions": { "method": "DELETE" }
}{
"id": "pol_01...",
"toolName": "rest:stripe",
"action": "deny",
"conditions": { "method": "DELETE" },
"createdAt": "2026-04-24T12:00:00.000Z"
}/tenants/:tenantId/policiesList active policies for a tenant, optionally filtered by agent.
policy:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| agentId | query | uuid | no | Filter by agent |
/tenants/:tenantId/policies/:policyIdGet a single policy by ID.
policy:read/tenants/:tenantId/policies/:policyIdReplace a policy rule.
policy:write/tenants/:tenantId/policies/:policyIdPartially update a policy rule.
policy:write/tenants/:tenantId/policies/:policyIdDelete a policy rule.
policy:delete{ "deleted": true, "id": "pol_01..." }/tenants/:tenantId/policies/evaluateDry-run: evaluate policies against a hypothetical tool call without writing to audit trail.
policy:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| agentId | body | uuid | no | Agent UUID to evaluate against |
| toolName | body | string | yes | Tool name to test |
| params | body | object | no | Tool parameters |
{
"decision": "deny",
"matchedPolicy": { "id": "pol_01...", "toolName": "rest:stripe", "action": "deny" },
"reason": "Matched deny rule for DELETE on rest:stripe"
}/tenants/:tenantId/policies/templatesList available built-in policy templates.
policy:readPlantillas de Políticas
/policy-templatesList all available built-in policy templates.
policy:read[
{
"id": "pii-protection",
"name": "PII Protection",
"description": "Block tool calls that expose PII fields",
"policyCount": 4
}
]/policy-templates/:templateIdGet a single template with all policy definitions.
policy:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| templateId | path | string | yes | Template slug (e.g. pii-protection) |
/tenants/:tenantId/policy-templates/:templateId/applyApply a template — creates all its policies in the tenant.
policy:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | uuid | yes | Tenant UUID |
| templateId | path | string | yes | Template slug |
| agentId | body | uuid | no | Scope policies to a specific agent (omit for tenant-wide) |
{
"templateName": "pii-protection",
"policiesCreated": 4,
"policyIds": ["pol_01...", "pol_02...", "pol_03...", "pol_04..."]
}/tenants/:tenantId/policy-templates/:templateId/removeRemove all policies that were applied from a template.
policy:delete{ "removed": 4, "templateName": "pii-protection" }/tenants/:tenantId/policy-templates/appliedList templates that have been applied to this tenant.
policy:readIncidentes
/tenants/:tenantId/incidentsList incidents with filtering by status, severity, and agent.
incident:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| status | query | string | no | Filter: open, investigating, resolved |
| severity | query | string | no | Filter: low, medium, high, critical |
| agentId | query | uuid | no | Filter by agent |
| limit | query | integer | no | Max results (default 50, max 500) |
| offset | query | integer | no | Pagination offset |
/tenants/:tenantId/incidentsOpen a new incident manually.
incident:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| agentId | body | uuid | no | Related agent |
| title | body | string | yes | Incident title |
| severity | body | string | yes | low, medium, high, or critical |
| type | body | string | no | injection, drift, policy_violation, anomaly, or manual |
| data | body | object | no | Arbitrary incident context data |
{
"id": "inc_01...",
"title": "Prompt injection detected",
"severity": "critical",
"status": "open",
"createdAt": "2026-04-24T12:00:00.000Z"
}/tenants/:tenantId/incidents/:incidentIdGet a single incident with full audit context.
incident:read/tenants/:tenantId/incidents/:incidentIdUpdate incident status or severity.
incident:triage| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| status | body | string | no | open, investigating, or resolved |
| severity | body | string | no | Updated severity |
| resolution | body | string | no | Resolution notes (required when status = resolved) |
/tenants/:tenantId/incidents/countGet incident counts grouped by status and severity.
incident:read{
"total": 42,
"byStatus": { "open": 12, "investigating": 5, "resolved": 25 },
"bySeverity": { "critical": 3, "high": 8, "medium": 18, "low": 13 }
}/tenants/:tenantId/incidents/:incidentId/auditList audit events linked to an incident.
incident:readRastro de Auditoría
/tenants/:tenantId/auditList audit events with filtering, pagination, and optional Merkle proof.
audit:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| agentId | query | uuid | no | Filter by agent |
| tool | query | string | no | Filter by tool name |
| outcome | query | string | no | Filter: allow, block, shadow |
| from | query | ISO8601 | no | Start timestamp |
| to | query | ISO8601 | no | End timestamp |
| limit | query | integer | no | Max results (default 100, max 1000) |
| offset | query | integer | no | Pagination offset |
{
"data": [
{
"id": "evt_01...",
"agentId": "agt_01HXYZ...",
"tool": "read_file",
"outcome": "block",
"riskScore": 0.87,
"decision": "injection_detected",
"timestamp": "2026-04-24T12:00:00.000Z",
"merkleHash": "sha256:abc123..."
}
],
"pagination": { "total": 1420, "limit": 100, "offset": 0, "hasMore": true }
}/tenants/:tenantId/audit/:eventIdGet a single audit event with full payload and Merkle proof.
audit:read/tenants/:tenantId/audit/verifyVerify the Merkle integrity of a batch of audit events.
audit:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| eventIds | body | uuid[] | yes | Array of event IDs to verify |
{
"verified": true,
"checkedCount": 50,
"tamperDetected": false
}/tenants/:tenantId/audit/exportStream audit events as NDJSON for bulk export.
audit:readResponse is streamed. Content-Type: application/x-ndjson. No pagination — returns all events in the window.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| from | query | ISO8601 | no | Start timestamp (required) |
| to | query | ISO8601 | no | End timestamp (required) |
| format | query | string | no | ndjson or json (default: ndjson) |
Puntuación de Riesgo
/tenants/:tenantId/risk/scoresGet current risk scores for all agents in a tenant.
risk:read{
"data": [
{
"agentId": "agt_01HXYZ...",
"agentName": "code-assistant",
"currentScore": 0.67,
"tier": "high",
"trend": "increasing",
"updatedAt": "2026-04-24T14:23:00Z"
}
]
}/tenants/:tenantId/risk/scores/:agentIdGet detailed risk score with component breakdown for a specific agent.
risk:read{
"agentId": "agt_01HXYZ...",
"currentScore": 0.67,
"tier": "high",
"components": {
"injectionScore": 0.12,
"toolDriftScore": 0.71,
"excessiveAgencyScore": 0.55,
"anomalyScore": 0.84,
"policyViolationRate": 0.03
},
"trend": "increasing",
"trendDelta": 0.14,
"updatedAt": "2026-04-24T14:23:00Z"
}/tenants/:tenantId/risk/scores/:agentId/historyGet risk score history for an agent (24h rolling window by default).
risk:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| window | query | string | no | Time window: 1h, 6h, 24h, 7d (default: 24h) |
/tenants/:tenantId/risk/scores/:agentId/recalculateForce an immediate risk score recalculation for an agent.
risk:write{
"agentId": "agt_01HXYZ...",
"previousScore": 0.67,
"newScore": 0.54,
"recalculatedAt": "2026-04-24T14:30:00Z"
}/tenants/:tenantId/risk/configGet risk enforcement configuration for the tenant.
risk:read{
"monitorThreshold": 0.30,
"blockThreshold": 0.80,
"autoLockThreshold": 0.95,
"humanReviewThreshold": 0.60
}/tenants/:tenantId/risk/configUpdate risk enforcement thresholds for the tenant.
risk:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| monitorThreshold | body | number | no | Score at which monitoring alerts trigger (0.0–1.0) |
| blockThreshold | body | number | no | Score at which auto-block activates (0.0–1.0) |
| autoLockThreshold | body | number | no | Score at which agent is suspended (0.0–1.0) |
| humanReviewThreshold | body | number | no | Score at which human review is required (0.0–1.0) |
/tenants/:tenantId/risk/baselines/:agentIdGet the behavioral baseline for an agent.
risk:read/tenants/:tenantId/risk/baselines/:agentIdReset an agent's behavioral baseline.
risk:write{ "reset": true, "agentId": "agt_01HXYZ..." }/tenants/:tenantId/risk/anomalies/analyzeRun an anomaly analysis on the last N hours of agent activity.
risk:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| agentId | body | uuid | no | Agent to analyze (omit for tenant-wide) |
| windowHours | body | integer | no | Lookback window (default: 24) |
{
"anomaliesDetected": true,
"results": [
{
"anomalyType": "tool_burst",
"anomalyScore": 0.91,
"explanation": "Agent called 47 tools in 60 seconds (4.2σ above baseline)"
}
]
}Cumplimiento
/tenants/:tenantId/compliance/checklistGet the current compliance posture with gap analysis.
compliance:read{
"overallScore": 0.87,
"passedChecks": 34,
"totalChecks": 39,
"sections": [
{
"id": "annex-iv-1",
"title": "General Description",
"status": "compliant",
"evidence": ["agent-registry", "system-purpose"]
},
{
"id": "annex-iv-4",
"title": "Risk Management System",
"status": "partial",
"gaps": ["enforcement-thresholds-not-set-for-3-agents"]
}
]
}/tenants/:tenantId/compliance/annex-iv/reportGenerate an Annex IV PDF report from the audit trail.
compliance:readResponse is streamed. Content-Type: application/pdf. The PDF is generated from the immutable audit trail with Merkle integrity proofs.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| periodStart | body | ISO8601 | yes | Report period start |
| periodEnd | body | ISO8601 | yes | Report period end |
| format | body | string | no | pdf or json (default: pdf) |
/tenants/:tenantId/compliance/reportsList previously generated compliance reports.
compliance:read/tenants/:tenantId/compliance/snapshotsGet compliance snapshots over time (for trending).
compliance:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integer | no | Max snapshots (default 30) |
/tenants/:tenantId/compliance/iso42001/gap-analysisISO 42001 gap analysis against the agent inventory.
compliance:read/tenants/:tenantId/compliance/nist-ai-rmf/gap-analysisNIST AI RMF gap analysis (Govern, Map, Measure, Manage functions).
compliance:read/tenants/:tenantId/compliance/regulatory-notificationsCreate a regulatory incident notification draft (EU AI Act Art. 73).
compliance:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| incidentId | body | uuid | yes | Related incident UUID |
| notificationDeadline | body | ISO8601 | no | Regulatory deadline (auto-calculated from incident date if omitted) |
Alertas
/tenants/:tenantId/alerts/rulesList alert rules.
alert:read/tenants/:tenantId/alerts/rulesCreate an alert rule.
alert:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| name | body | string | yes | Rule name |
| condition | body | string | yes | CEL condition expression (e.g. riskScore >= 0.70) |
| severity | body | string | yes | low, medium, high, or critical |
| channels | body | string[] | no | Delivery channels: webhook, email, slack |
| webhookUrl | body | string | no | Webhook delivery URL |
| agentId | body | uuid | no | Scope to a specific agent |
/tenants/:tenantId/alerts/rules/:ruleIdUpdate an alert rule.
alert:write/tenants/:tenantId/alerts/rules/:ruleIdDelete an alert rule.
alert:delete/tenants/:tenantId/alerts/eventsList fired alert events.
alert:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integer | no | Max results (default 100, max 500) |
| from | query | ISO8601 | no | Start timestamp |
Servidores MCP
/tenants/:tenantId/mcp-serversRegister an MCP server for scanning and tool discovery.
mcp_server:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| name | body | string | yes | MCP server display name |
| url | body | string | yes | MCP server URL or stdio command |
| transport | body | string | no | http-sse or stdio (default: http-sse) |
| scanOnRegister | body | boolean | no | Run initial scan on registration (default: true) |
{
"id": "mcp_01...",
"name": "filesystem-server",
"url": "http://localhost:8080",
"transport": "http-sse",
"createdAt": "2026-04-24T12:00:00.000Z"
}/tenants/:tenantId/mcp-serversList registered MCP servers.
mcp_server:read/tenants/:tenantId/mcp-servers/:mcpServerIdGet a single MCP server with tool inventory.
mcp_server:read/tenants/:tenantId/mcp-servers/:mcpServerIdUpdate MCP server configuration.
mcp_server:write/tenants/:tenantId/mcp-servers/:mcpServerIdDeregister an MCP server.
mcp_server:delete{ "deleted": true, "id": "mcp_01..." }/tenants/:tenantId/mcp-servers/:mcpServerId/refresh-toolsRe-discover tools from the MCP server.
mcp_server:write{
"toolsDiscovered": 12,
"toolsAdded": 2,
"toolsRemoved": 0,
"refreshedAt": "2026-04-24T12:00:00.000Z"
}/tenants/:tenantId/mcp-servers/:mcpServerId/scanRun a security scan on the MCP server's tools.
mcp_server:write{
"scanId": "scan_01...",
"status": "completed",
"vulnerabilities": 1,
"toolCount": 5,
"scanDuration": 1240
}/tenants/:tenantId/mcp-servers/:mcpServerId/scansGet scan history for an MCP server.
mcp_server:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integer | no | Max results (default 20, max 100) |
/tenants/:tenantId/scansTenant-wide scan history across all MCP servers.
mcp_server:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integer | no | Max results (default 50, max 200) |
Revisiones
Cola de revisión humana para llamadas de herramientas que requieren aprobación antes de ejecutarse.
/tenants/:tenantId/reviewsList pending reviews with filtering and pagination.
review:read| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| status | query | string | no | Filter: pending, approved, denied |
| agentId | query | uuid | no | Filter by agent |
| limit | query | integer | no | Max results (default 50, max 500) |
| offset | query | integer | no | Pagination offset |
/tenants/:tenantId/reviews/countGet review counts by status.
review:read{ "pending": 5, "approved": 120, "denied": 8 }/tenants/:tenantId/reviews/:reviewIdGet a single review with agent name.
review:read/tenants/:tenantId/reviews/:reviewId/decideApprove or deny a pending review.
review:triage| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| decision | body | string | yes | approved or denied |
| comment | body | string | no | Optional reviewer comment |
{
"decision": "approved",
"comment": "Verified safe — one-time file access needed"
}Notificaciones
/tenants/:tenantId/notificationsList in-app notifications for the current user.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| unreadOnly | query | boolean | no | Filter to unread only |
| limit | query | integer | no | Max results (default 50, max 200) |
/tenants/:tenantId/notifications/:id/readMark a single notification as read.
/tenants/:tenantId/notifications/read-allMark all unread notifications as read.
{ "marked": 12 }Pasaportes
Los Pasaportes de Agente proporcionan tarjetas de identidad verificables para agentes de IA. Requiere el plan Business o superior.
/tenants/:tenantId/agents/:agentId/passportGet an agent's passport with risk assessment, compliance status, and signature.
passport:readRequires agent_passport feature entitlement (Business+ plan).
/tenants/:tenantId/agents/:agentId/passportUpdate passport display metadata.
passport:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| displayName | body | string | no | Public display name |
| description | body | string | no | Public description |
| avatarUrl | body | string | no | Avatar image URL (SSRF-protected) |
| visibility | body | string | no | private, internal, or public |
/tenants/:tenantId/agents/:agentId/passport/refreshRecompute and re-sign the passport with latest data.
passport:write/tenants/:tenantId/agents/:agentId/passport/publishPublish the passport for external verification.
passport:writePublishing as public requires elevated role (security_manager, tenant_admin, or platform_admin).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| visibility | body | string | no | public or internal (default: internal) |
/tenants/:tenantId/agents/:agentId/passport/unpublishUnpublish a passport — sets visibility to private.
passport:write/public/passports/:tenantSlug/:agentSlugView a published passport (public, unauthenticated).
Rate-limited to 60 requests/minute per IP. Returns cached response (max-age 300s).
/public/passports/:tenantSlug/:agentSlug/verifyVerify a passport's cryptographic signature (public, unauthenticated).
{
"verified": true,
"valid": true,
"passportHash": "sha256:abc123...",
"signature": "base64:...",
"signedAt": "2026-04-24T12:00:00.000Z",
"keyId": "key_01...",
"publicKey": "-----BEGIN PUBLIC KEY-----..."
}/public/passports/:tenantSlug/:agentSlug/badge.svgRender an embeddable SVG badge for the agent (public, unauthenticated).
Rate-limited to 300 requests/minute per IP. Content-Type: image/svg+xml.
Facturación
/billing/statusCurrent plan tier and subscription status.
tenant:read{
"planTier": "pro",
"billingState": "active",
"hasStripeCustomer": true,
"hasSubscription": true
}/billing/entitlementsFeature entitlements and limits for the current plan.
tenant:read{
"planTier": "pro",
"billingState": "active",
"entitlements": {
"maxAgents": 50,
"includedToolCalls": 100000,
"retentionDays": 365,
"features": ["agent_passport", "sso", "custom_policies"]
}
}/billing/usageCurrent month usage and plan limits.
tenant:read{
"currentAgentCount": 12,
"maxAgents": 50,
"currentToolCalls": 45230,
"includedToolCalls": 100000,
"overageRate": 0.001,
"billingPeriodStart": "2026-04-01T00:00:00.000Z",
"billingPeriodEnd": "2026-04-30T23:59:59.999Z",
"retentionDays": 365
}/billing/checkoutCreate a Stripe Checkout session for plan upgrade.
tenant:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tier | body | string | yes | Target plan: free, team, starter, pro, business |
| successPath | body | string | no | Redirect path after success |
| cancelPath | body | string | no | Redirect path on cancel |
{ "checkoutUrl": "https://checkout.stripe.com/c/pay_..." }/billing/portalCreate a Stripe Customer Portal session for subscription management.
tenant:write{ "portalUrl": "https://billing.stripe.com/p/session_..." }Configuraciones de Exportación
Configura la exportación automatizada del rastro de auditoría a destinos S3, webhooks o syslog. Las credenciales se cifran en reposo (AES-256-GCM) y nunca se devuelven en las respuestas de la API.
/tenants/:tenantId/export-configsCreate an export configuration.
export:write| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| name | body | string | yes | Config display name |
| destinationType | body | string | yes | s3, webhook, or syslog |
| config | body | object | yes | Destination-specific config (bucket, url, host, etc.) |
| credentials | body | object | no | Auth credentials (encrypted at rest, never returned) |
| filters | body | object | no | Event filters (agent, tool, outcome, etc.) |
| intervalSeconds | body | integer | no | Export interval (30–86400 seconds) |
| format | body | string | no | ndjson or json (default: ndjson) |
| enabled | body | boolean | no | Active on creation (default: true) |
{
"name": "S3 Audit Export",
"destinationType": "s3",
"config": {
"bucket": "acme-audit-logs",
"region": "eu-west-1",
"prefix": "shieldagent/"
},
"credentials": {
"accessKeyId": "AKIA...",
"secretAccessKey": "wJalr..."
},
"intervalSeconds": 300,
"format": "ndjson"
}/tenants/:tenantId/export-configsList export configs (credentials redacted).
export:read/tenants/:tenantId/export-configs/:configIdUpdate an export config (partial update, credentials redacted in response).
export:write/tenants/:tenantId/export-configs/:configIdDelete an export configuration.
export:delete/tenants/:tenantId/export-configs/:configId/testTest the export adapter connection.
export:write{ "success": true, "latencyMs": 245 }API de Veredicto
Responsabilidad de aplicación
La API de Veredicto ejecuta el pipeline de seguridad completo de ShieldAgent y devuelve un veredicto. Tu código de servidor es responsable de aplicar ese veredicto — ShieldAgent no reenvía ni bloquea el tráfico directamente. Si tu código ignora un veredicto block, la llamada a la herramienta se ejecuta de todos modos. Todos los veredictos de escaneo se registran en el rastro de auditoría con source: "verdict_api"; la detección de anomalías puede marcar agentes con 100% de veredictos de bloqueo pero con ejecución de herramientas continua.
La API de Veredicto permite el escaneo del lado del servidor para clientes que poseen y operan su propio servidor de API o MCP (Posición de Despliegue E). En lugar de enrutar el tráfico a través del proxy de ShieldAgent, tu servidor envía el payload de la solicitud a ShieldAgent, recibe un veredicto de seguridad y lo aplica localmente. La comunicación del agente con tu servidor no cambia — no se modifican mensajes MCP, no se añaden encabezados HTTP.
Modelo de autenticación — clave de API de tenant, no JWT de usuario
Los endpoints de la API de Veredicto se autentican con una clave de API con ámbito de tenant (token Bearer), no el JWT de usuario emitido por /auth/login. Trata esta clave como un secreto del lado del servidor — nunca la expongas a los clientes agentes.
URL base (servicio proxy): https://proxy.shieldagent.io | Autoalojado: http://localhost:3100
/tenants/:tenantId/scanSubmit a tool call or API request for security scanning. Returns a verdict (allow / block / human_review). Your server must enforce the verdict — ShieldAgent does not forward traffic.
Auth: Bearer <tenant-api-key>. Rate-limited per tenant and per agent (Redis-backed). An audit event is written on every call with source: "verdict_api". The same multi-stage pipeline as the inline proxy runs — forwarding is skipped.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | string (uuid) | yes | Your tenant UUID |
| agentId | body | string (uuid) | no | ShieldAgent agent UUID. Optional — omit when your server cannot identify the caller (e.g. typical MCP server, which has no agent identity in the protocol). When provided the agent must belong to this tenant; cross-tenant IDs are rejected with 403. When omitted the pipeline runs with tenant-level policies only. |
| clientHint | body | string | no | MCP clientInfo.name or similar client software identifier (e.g. "Claude Desktop"). Used for best-effort agent matching when agentId is unavailable: if exactly one registered agent matches, per-agent policies apply; otherwise falls back to tenant-level. Ignored when agentId is provided. |
| toolName | body | string | yes | Name of the tool being called (e.g. "read_file", "api:POST:/payments") |
| params | body | object | yes | Tool call parameters as a JSON object |
| include_findings | body | boolean | no | Request detailed findings in the response. Requires the verdictDetailedFindings tenant permission flag (off by default — see Response Tiering below). Without permission this field is ignored. |
| context.transport | body | "mcp" | "rest" | "custom" | no | Transport protocol between agent and your server |
| context.sourceIp | body | string | no | IP address of the agent. Used for per-IP rate limiting. |
| context.sessionId | body | string | no | Session identifier. Used for excessive agency detection across calls in the same session. |
{
"agentId": "a1b2c3d4-0000-0000-0000-000000000001", // optional
"clientHint": "Claude Desktop", // optional
"toolName": "read_file",
"params": { "path": "/etc/passwd" },
"include_findings": false,
"context": {
"transport": "mcp",
"sourceIp": "10.0.1.5",
"sessionId": "sess-abc123"
}
}{
"action": "block", // "allow" | "block" | "human_review"
"reason": "Security threat detected",
"riskScore": 87,
"auditEventId": "evt-a1b2c3d4-0000-0000-0000-000000000001",
"reviewId": null // set when action is "human_review"
}Niveles de respuesta — include_findings: true + verdictDetailedFindings tenant permission
Los hallazgos detallados están desactivados por defecto. La respuesta predeterminada omite deliberadamente nombres de escáneres, patrones de detección y detalles de estrategia para prevenir ataques de evasión iterativa (refleja el modelo de hallazgos DLP). Habilitar solo para depuración o pruebas de integración.
{
"action": "block",
"reason": "Prompt injection detected in tool arguments",
"findings": [
{
"type": "injection",
"severity": "critical",
"detail": "Path traversal pattern detected",
"scanner": "regex"
}
],
"riskScore": 87,
"auditEventId": "evt-a1b2c3d4-...",
"reviewId": null
}Respuestas de error
Cuándo omitir agentId
| Escenario | agentId | Comportamiento del pipeline |
|---|---|---|
| Servidor MCP (típico) | omitir | Solo políticas a nivel de tenant. Opcionalmente pasar clientHint del handshake MCP clientInfo.name. |
| API HTTP con mapeo de autenticación de agente | proveer | Pipeline completo por agente: políticas, puntuación de riesgo, límites de tasa, línea base, herramientas aprobadas. |
| API HTTP sin mapeo de agente | omitir | Solo políticas a nivel de tenant. Los límites de tasa se aplican por tenant. |
/tenants/:tenantId/verdict-confirmationsReport whether a verdict was enforced by your server. Optional callback that closes the audit loop and satisfies EU AI Act Art. 9 enforcement evidence requirements. Tenants that never call this show as 'enforcement unknown' in compliance reports.
Not required — enforcement confirmation is voluntary. Contributes to the Verdict Enforcement Rate metric in Grafana. Call after executing or rejecting the tool call, not before.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| tenantId | path | string (uuid) | yes | Your tenant UUID |
| auditEventId | body | string (uuid) | yes | The auditEventId returned by POST /scan |
| executed | body | boolean | yes | true if the tool call was executed (verdict was "allow" or human review approved); false if it was rejected (verdict was "block" or human review denied) |
{
"auditEventId": "evt-a1b2c3d4-0000-0000-0000-000000000001",
"executed": false
}{ "recorded": true }Salud
/healthzLiveness probe. Returns service status and timestamp.
Excluded from rate limiting. Use for Kubernetes liveness/readiness probes.
{
"status": "ok",
"timestamp": "2026-04-24T12:00:00.000Z"
}Especificación OpenAPI
La especificación completa OpenAPI 3.1.0 está disponible para importar en Postman, Insomnia o cualquier herramienta compatible con OpenAPI. Consulta la página de Referencia OpenAPI para las URLs de especificación e instrucciones de generación de clientes.
# Serve Swagger UI locally
npx @redocly/cli preview-docs docs/openapi/shieldagent-api.yaml