feat: Phase 1 MVP — complete AgentIdP implementation

Implements all P0 features per OpenSpec change phase-1-mvp-implementation:
- Agent Registry Service (CRUD) — full lifecycle management
- OAuth 2.0 Token Service (Client Credentials flow)
- Credential Management (generate, rotate, revoke)
- Immutable Audit Log Service

Tech: Node.js 18+, TypeScript 5.3+ strict, Express 4.18+, PostgreSQL 14+, Redis 7+
Standards: OpenAPI 3.0 specs, DRY/SOLID, zero `any` types
Quality: 18 unit test suites, 244 tests passing, 97%+ coverage
OpenAPI: 4 complete specs (14 endpoints total)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
SentryAgent.ai Developer
2026-03-28 09:14:41 +00:00
parent 245f8df427
commit d3530285b9
78 changed files with 20590 additions and 1 deletions

283
src/types/index.ts Normal file
View File

@@ -0,0 +1,283 @@
/**
* Shared TypeScript interfaces and types for SentryAgent.ai AgentIdP.
* All interfaces and types live here — no inline type definitions in service/controller files.
*/
// ============================================================================
// Enumerations / Union Types
// ============================================================================
/** Functional classification of an AI agent. */
export type AgentType =
| 'screener'
| 'classifier'
| 'orchestrator'
| 'extractor'
| 'summarizer'
| 'router'
| 'monitor'
| 'custom';
/** Lifecycle status of an AI agent. */
export type AgentStatus = 'active' | 'suspended' | 'decommissioned';
/** Target deployment environment for an agent. */
export type DeploymentEnv = 'development' | 'staging' | 'production';
/** Lifecycle status of an agent credential. */
export type CredentialStatus = 'active' | 'revoked';
/** OAuth 2.0 scope values supported by this IdP. */
export type OAuthScope = 'agents:read' | 'agents:write' | 'tokens:read' | 'audit:read';
/** Audit action identifiers for all significant platform events. */
export type AuditAction =
| 'agent.created'
| 'agent.updated'
| 'agent.decommissioned'
| 'agent.suspended'
| 'agent.reactivated'
| 'token.issued'
| 'token.revoked'
| 'token.introspected'
| 'credential.generated'
| 'credential.rotated'
| 'credential.revoked'
| 'auth.failed';
/** Outcome of an audited action. */
export type AuditOutcome = 'success' | 'failure';
// ============================================================================
// Agent Registry
// ============================================================================
/** Full representation of a registered AI agent identity. */
export interface IAgent {
agentId: string;
email: string;
agentType: AgentType;
version: string;
capabilities: string[];
owner: string;
deploymentEnv: DeploymentEnv;
status: AgentStatus;
createdAt: Date;
updatedAt: Date;
}
/** Request body for registering a new AI agent. */
export interface ICreateAgentRequest {
email: string;
agentType: AgentType;
version: string;
capabilities: string[];
owner: string;
deploymentEnv: DeploymentEnv;
}
/** Request body for partially updating an agent. */
export interface IUpdateAgentRequest {
agentType?: AgentType;
version?: string;
capabilities?: string[];
owner?: string;
deploymentEnv?: DeploymentEnv;
status?: AgentStatus;
}
/** Paginated list of agents. */
export interface IPaginatedAgentsResponse {
data: IAgent[];
total: number;
page: number;
limit: number;
}
/** Query filters for listing agents. */
export interface IAgentListFilters {
owner?: string;
agentType?: AgentType;
status?: AgentStatus;
page: number;
limit: number;
}
// ============================================================================
// Credentials
// ============================================================================
/** A credential record for an AI agent (clientSecret never included). */
export interface ICredential {
credentialId: string;
clientId: string;
status: CredentialStatus;
createdAt: Date;
expiresAt: Date | null;
revokedAt: Date | null;
}
/** Credential with the plain-text secret — returned once only on create/rotate. */
export interface ICredentialWithSecret extends ICredential {
clientSecret: string;
}
/** Database row for a credential, including the bcrypt hash. */
export interface ICredentialRow extends ICredential {
secretHash: string;
}
/** Request body for generating or rotating a credential. */
export interface IGenerateCredentialRequest {
expiresAt?: string | Date;
}
/** Paginated list of credentials. */
export interface IPaginatedCredentialsResponse {
data: ICredential[];
total: number;
page: number;
limit: number;
}
/** Query filters for listing credentials. */
export interface ICredentialListFilters {
status?: CredentialStatus;
page: number;
limit: number;
}
// ============================================================================
// OAuth2 Token
// ============================================================================
/** JWT access token payload (claims). */
export interface ITokenPayload {
/** Subject — agentId. */
sub: string;
/** client_id — agentId. */
client_id: string;
/** Space-separated OAuth 2.0 scopes. */
scope: string;
/** JWT ID — UUID v4. */
jti: string;
/** Issued at (Unix seconds). */
iat: number;
/** Expiry (Unix seconds). */
exp: number;
}
/** OAuth 2.0 token request (form-encoded). */
export interface ITokenRequest {
grant_type: string;
client_id?: string;
client_secret?: string;
scope?: string;
}
/** Successful OAuth 2.0 token response. */
export interface ITokenResponse {
access_token: string;
token_type: 'Bearer';
expires_in: number;
scope: string;
}
/** OAuth 2.0 error response (RFC 6749 §5.2). */
export interface IOAuth2ErrorResponse {
error: string;
error_description: string;
}
/** Token introspection request (RFC 7662). */
export interface IIntrospectRequest {
token: string;
token_type_hint?: string;
}
/** Token introspection response (RFC 7662). */
export interface IIntrospectResponse {
active: boolean;
sub?: string;
client_id?: string;
scope?: string;
token_type?: string;
iat?: number;
exp?: number;
}
/** Token revocation request (RFC 7009). */
export interface IRevokeRequest {
token: string;
token_type_hint?: string;
}
// ============================================================================
// Audit Log
// ============================================================================
/** An immutable audit event record. */
export interface IAuditEvent {
eventId: string;
agentId: string;
action: AuditAction;
outcome: AuditOutcome;
ipAddress: string;
userAgent: string;
metadata: Record<string, unknown>;
timestamp: Date;
}
/** Input for creating a new audit event. */
export interface ICreateAuditEventInput {
agentId: string;
action: AuditAction;
outcome: AuditOutcome;
ipAddress: string;
userAgent: string;
metadata: Record<string, unknown>;
}
/** Paginated list of audit events. */
export interface IPaginatedAuditEventsResponse {
data: IAuditEvent[];
total: number;
page: number;
limit: number;
}
/** Query filters for the audit log. */
export interface IAuditListFilters {
agentId?: string;
action?: AuditAction;
outcome?: AuditOutcome;
fromDate?: string;
toDate?: string;
page: number;
limit: number;
}
// ============================================================================
// API Error Response
// ============================================================================
/** Standard error response envelope used across all SentryAgent.ai APIs. */
export interface IErrorResponse {
code: string;
message: string;
details?: Record<string, unknown>;
}
// ============================================================================
// Express type augmentation
// ============================================================================
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Express {
interface Request {
/** Decoded JWT payload attached by the auth middleware. */
user?: ITokenPayload;
}
}
}