sin-code-database / src /lib /telemetry /ZeroTrustAuth.ts
GitHub Actions
Deploy SIN-Code-Database from GitHub Actions
720c6ed
Raw
History Blame Contribute Delete
2.42 kB
import { verify } from 'jsonwebtoken';
import { resolveTemplateAgentConfig } from '../../metadata.js';
import { createTemplateLogger } from './SentinelLogger.js';
import type { IncomingMessage } from 'node:http';
// We fetch the public key (or use a shared secret if configured) from SIN-Authenticator's OIDC jwks endpoint or env
const OIDC_PUBLIC_KEY = process.env.SIN_OIDC_PUBLIC_KEY || process.env.SIN_SHARED_SECRET || '';
export type AuthContext = {
subject: string;
roles: string[];
claims: Record<string, unknown>;
isValid: boolean;
error?: string;
};
export async function verifyZeroTrustToken(request: IncomingMessage, runId?: string): Promise<AuthContext> {
const logger = createTemplateLogger(runId);
const authHeader = request.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
await logger.failed('auth.zero_trust', 'auth.token.missing', new Error('Missing or malformed Authorization header'));
return { subject: 'anonymous', roles: [], claims: {}, isValid: false, error: 'missing_token' };
}
const token = authHeader.split(' ')[1];
if (!OIDC_PUBLIC_KEY) {
// If the fleet runs in a mode without strict OIDC enforcement configured yet,
// we log a warning but might fail closed depending on fleet policy.
// For Epic #195, we want to enforce zero-trust strictly when keys are present.
await logger.log({
surface: 'auth.zero_trust',
event: 'auth.keys.missing',
level: 'warn',
status: 'failed',
details: { note: 'No SIN_OIDC_PUBLIC_KEY or SIN_SHARED_SECRET configured for verification.' }
});
return { subject: 'anonymous', roles: [], claims: {}, isValid: false, error: 'missing_keys' };
}
try {
const decoded = verify(token, OIDC_PUBLIC_KEY, { algorithms: ['RS256', 'HS256'] }) as Record<string, unknown>;
await logger.succeeded('auth.zero_trust', 'auth.token.verified', { subject: decoded.sub });
return {
subject: String(decoded.sub || 'unknown'),
roles: Array.isArray(decoded.roles) ? decoded.roles.map(String) : [],
claims: decoded,
isValid: true
};
} catch (error) {
await logger.failed('auth.zero_trust', 'auth.token.rejected', error);
return {
subject: 'anonymous',
roles: [],
claims: {},
isValid: false,
error: error instanceof Error ? error.message : String(error)
};
}
}