openapi: 3.0.3 info: title: SentryAgent.ai — Audit Log Service version: 1.0.0 description: | The Audit Log Service provides a queryable, immutable, compliance-ready event log of all significant actions performed by agents and administrators on the SentryAgent.ai AgentIdP platform. **Immutability**: Audit events are written internally only — there are no API endpoints to create, modify, or delete audit records. The log is append-only by design. **Automatic event capture**: The following actions are automatically logged: | Action | Description | |--------|-------------| | `agent.created` | A new agent was registered | | `agent.updated` | Agent metadata was modified | | `agent.decommissioned` | An agent was decommissioned | | `agent.suspended` | An agent was suspended | | `agent.reactivated` | A suspended agent was reactivated | | `token.issued` | An access token was issued | | `token.revoked` | An access token was revoked | | `token.introspected` | A token was introspected | | `credential.generated` | New credentials were generated | | `credential.rotated` | A credential was rotated | | `credential.revoked` | A credential was revoked | | `auth.failed` | An authentication attempt failed | **Free Tier**: Audit log retention is 90 days. Events older than 90 days are automatically purged on the free tier. **Required scope**: `audit:read` servers: - url: http://localhost:3000/api/v1 description: Local development server - url: https://api.sentryagent.ai/v1 description: Production server tags: - name: Audit Log description: Query immutable audit events for compliance and governance components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT description: | JWT access token with `audit:read` scope, obtained via `POST /token`. Include as: `Authorization: Bearer ` schemas: AuditAction: type: string description: The action that triggered the audit event. enum: - agent.created - agent.updated - agent.decommissioned - agent.suspended - agent.reactivated - token.issued - token.revoked - token.introspected - credential.generated - credential.rotated - credential.revoked - auth.failed example: token.issued AuditOutcome: type: string description: Whether the action succeeded or failed. enum: - success - failure example: success AuditEvent: type: object description: | An immutable audit event record representing a single significant action that occurred within the SentryAgent.ai platform. required: - eventId - agentId - action - outcome - ipAddress - userAgent - metadata - timestamp properties: eventId: type: string format: uuid description: Immutable, system-assigned unique identifier for this audit event. readOnly: true example: "f1e2d3c4-b5a6-7890-cdef-123456789012" agentId: type: string format: uuid description: > The `agentId` of the agent that triggered this event. For system-generated events (e.g. automatic token expiry), this field refers to the affected agent. example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" action: $ref: '#/components/schemas/AuditAction' outcome: $ref: '#/components/schemas/AuditOutcome' ipAddress: type: string description: > IP address of the client that initiated the request. IPv4 or IPv6 format. May be `0.0.0.0` for system-generated events. example: "203.0.113.42" userAgent: type: string description: > HTTP `User-Agent` header value from the originating request. May be `SentryAgent-System/1.0` for internally generated events. example: "SentryAgent-SDK/1.0.0 Node.js/18.19.0" metadata: type: object description: | Action-specific structured data providing additional context. Schema varies by `action`: - `token.issued`: includes `scope`, `expiresAt` - `credential.rotated`: includes `credentialId` - `agent.created`: includes `agentType`, `owner` - `auth.failed`: includes `reason`, `clientId` additionalProperties: true example: scope: "agents:read agents:write" expiresAt: "2026-03-28T10:00:00.000Z" timestamp: type: string format: date-time description: ISO 8601 timestamp when the event occurred. readOnly: true example: "2026-03-28T09:01:00.000Z" PaginatedAuditEventsResponse: type: object description: Paginated list of audit events. required: - data - total - page - limit properties: data: type: array items: $ref: '#/components/schemas/AuditEvent' total: type: integer description: Total number of audit events matching the query filters. example: 1423 page: type: integer description: Current page number (1-based). example: 1 limit: type: integer description: Number of items per page. example: 50 ErrorResponse: type: object description: Standard error response envelope. required: - code - message properties: code: type: string description: Machine-readable error code. example: "AUDIT_EVENT_NOT_FOUND" message: type: string description: Human-readable description of the error. example: "Audit event with the specified ID was not found." details: type: object description: Optional structured details about the error. additionalProperties: true example: {} responses: Unauthorized: description: Missing or invalid Bearer token. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: code: "UNAUTHORIZED" message: "A valid Bearer token is required to access this resource." Forbidden: description: Valid token but insufficient permissions. Requires `audit:read` scope. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: code: "INSUFFICIENT_SCOPE" message: "The 'audit:read' scope is required to access audit logs." NotFound: description: The requested audit event was not found. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: code: "AUDIT_EVENT_NOT_FOUND" message: "Audit event with the specified ID was not found." TooManyRequests: description: Rate limit exceeded. headers: X-RateLimit-Limit: schema: type: integer description: Maximum requests allowed per minute. example: 100 X-RateLimit-Remaining: schema: type: integer description: Requests remaining in the current window. example: 0 X-RateLimit-Reset: schema: type: integer description: Unix timestamp when the rate limit window resets. example: 1743155400 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: code: "RATE_LIMIT_EXCEEDED" message: "Too many requests. Please retry after the rate limit window resets." InternalServerError: description: Unexpected server error. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: code: "INTERNAL_SERVER_ERROR" message: "An unexpected error occurred. Please try again later." security: - BearerAuth: [] paths: /audit: get: operationId: queryAuditLog tags: - Audit Log summary: Query audit log description: | Returns a paginated, filtered list of audit events. Results are ordered by `timestamp` descending (most recent first). **Requires**: Bearer token with `audit:read` scope. **Retention**: On the free tier, only events from the last 90 days are accessible. Requests for older events will return an empty result set, not an error. **Filtering**: Multiple filters can be combined (logical AND). All filter parameters are optional. parameters: - name: page in: query description: Page number (1-based). Defaults to `1`. required: false schema: type: integer minimum: 1 default: 1 example: 1 - name: limit in: query description: Number of results per page. Defaults to `50`, maximum `200`. required: false schema: type: integer minimum: 1 maximum: 200 default: 50 example: 50 - name: agentId in: query description: Filter events to those triggered by a specific agent (UUID). required: false schema: type: string format: uuid example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" - name: action in: query description: Filter events by action type. required: false schema: $ref: '#/components/schemas/AuditAction' - name: outcome in: query description: Filter events by outcome. required: false schema: $ref: '#/components/schemas/AuditOutcome' - name: fromDate in: query description: | Filter events at or after this ISO 8601 timestamp (inclusive). On free tier, cannot be older than 90 days from today. required: false schema: type: string format: date-time example: "2026-03-01T00:00:00.000Z" - name: toDate in: query description: Filter events at or before this ISO 8601 timestamp (inclusive). required: false schema: type: string format: date-time example: "2026-03-28T23:59:59.999Z" responses: '200': description: Audit events returned successfully. headers: X-RateLimit-Limit: schema: type: integer example: 100 X-RateLimit-Remaining: schema: type: integer example: 95 X-RateLimit-Reset: schema: type: integer example: 1743155400 content: application/json: schema: $ref: '#/components/schemas/PaginatedAuditEventsResponse' example: data: - eventId: "f1e2d3c4-b5a6-7890-cdef-123456789012" agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" action: "token.issued" outcome: "success" ipAddress: "203.0.113.42" userAgent: "SentryAgent-SDK/1.0.0 Node.js/18.19.0" metadata: scope: "agents:read agents:write" expiresAt: "2026-03-28T10:01:00.000Z" timestamp: "2026-03-28T09:01:00.000Z" - eventId: "e2d3c4b5-a6f7-8901-bcde-f23456789013" agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" action: "credential.generated" outcome: "success" ipAddress: "203.0.113.42" userAgent: "SentryAgent-SDK/1.0.0 Node.js/18.19.0" metadata: credentialId: "c9d8e7f6-a5b4-3210-fedc-ba9876543210" timestamp: "2026-03-28T09:00:00.000Z" - eventId: "d3c4b5a6-f7e8-9012-cdef-345678901234" agentId: "b2c3d4e5-f6a7-8901-bcde-f12345678901" action: "auth.failed" outcome: "failure" ipAddress: "198.51.100.17" userAgent: "python-requests/2.31.0" metadata: reason: "invalid_client_secret" clientId: "b2c3d4e5-f6a7-8901-bcde-f12345678901" timestamp: "2026-03-28T08:45:00.000Z" total: 1423 page: 1 limit: 50 '400': description: Invalid query parameters. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: invalidDate: summary: Invalid date format value: code: "VALIDATION_ERROR" message: "Invalid query parameter value." details: field: "fromDate" reason: "Must be a valid ISO 8601 date-time string." invalidDateRange: summary: fromDate is after toDate value: code: "VALIDATION_ERROR" message: "Invalid date range." details: reason: "fromDate must be before or equal to toDate." retentionExceeded: summary: Requested date is outside retention window value: code: "RETENTION_WINDOW_EXCEEDED" message: "Free tier audit log retention is 90 days. Requested date is outside the retention window." details: retentionDays: 90 earliestAvailable: "2025-12-28T00:00:00.000Z" '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' /audit/{eventId}: parameters: - name: eventId in: path description: The unique UUID identifier of the audit event. required: true schema: type: string format: uuid example: "f1e2d3c4-b5a6-7890-cdef-123456789012" get: operationId: getAuditEventById tags: - Audit Log summary: Get a single audit event by ID description: | Retrieves a single, immutable audit event by its unique `eventId`. **Requires**: Bearer token with `audit:read` scope. **Retention**: Free tier events older than 90 days are not accessible and will return `404 Not Found`. responses: '200': description: Audit event returned successfully. headers: X-RateLimit-Limit: schema: type: integer example: 100 X-RateLimit-Remaining: schema: type: integer example: 94 X-RateLimit-Reset: schema: type: integer example: 1743155400 content: application/json: schema: $ref: '#/components/schemas/AuditEvent' example: eventId: "f1e2d3c4-b5a6-7890-cdef-123456789012" agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" action: "token.issued" outcome: "success" ipAddress: "203.0.113.42" userAgent: "SentryAgent-SDK/1.0.0 Node.js/18.19.0" metadata: scope: "agents:read agents:write" expiresAt: "2026-03-28T10:01:00.000Z" timestamp: "2026-03-28T09:01:00.000Z" '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError'