Logging, Audit, and Permission Enforcement Constraints¶
This spec captures how logs and audit records should be emitted plus which permission mechanisms must be used so that feature-level specs can align with the existing observability and compliance stack.
1. Logging Channel Expectations¶
- Canonical logger: All runtime logs must go through
backend/src/lib/logger.ts, which configures Pino withservice: 'backend', the currentNODE_ENV, and apino-prettytransport for console-friendly output. Avoid ad-hocconsole.logstatements in business logic; uselogger.info,logger.warn,logger.error, etc., and tag each entry with the service and component context. - Log level control: Runtime verbosity is controlled via
LOG_LEVEL, defaulting toinfo. When feature-level debugging is necessary, temporarily raise the level locally but revert before merging. Do not change the transport configuration, as structured metadata is required downstream. - Fluent Bit forwarding: Infrastructure expects logs to flow through Fluent Bit (URL provided via
FLUENT_BIT_URL). Ensure the environment variable is populated in deployment manifests; no code should bypass this by pushing directly to third-party telemetry without a shared schema (timestamp, level, service, worker_type, component, metadata).
2. Audit Logging Discipline¶
- Use AuditLogger: Security-sensitive actions (role changes, token issuance, onboarding, destructive operations) must call
AuditLogger.getInstance().log(entry)as seen inbackend/src/lib/audit-logger.ts. It writes to both theaudit_logstable and the Fluent Bit endpoint, guaranteeing persistence and observability. - Entry content: Provide
action,details,severity(Low/Medium/High), and user context (userId,userName,userEmail). Always include request metadata (requestId,clientIp,userAgent) so each record can be traced back to a request. - Failure handling: The audit logger retries both sinks in parallel (
Promise.all). If Fluent Bit is unreachable, log the failure locally but do not skip the audit entry—the database write is the canonical compliance record. Feature handlers shouldawait auditLog(...)before acknowledging success.
3. Permission Enforcement Workflow¶
- Authenticate & authorize: All new endpoints must use the
authenticatemiddleware (Kratos → Kong headers → JWT). Afterward, applyauthorizeWithOPAso the gateway’s RBAC policy is enforced again inside the service. - Backend role checks: For ultra-critical endpoints (e.g., metrics
/metricsor any admin dashboard), layerrequireRoleon top of OPA. Don’t duplicate role lists; import them fromgateway/opa/policies/rbac.regoand document any divergence in the feature spec. - Role additions: Introducing a new role requires updating the Prisma
roletype, Kratos schema traits, and the OPA policy. Make sure the role appears in issued JWTs and seeded demo data to keep downstream logic consistent. - Audit permission changes: Whenever permissions change, log before/after states. Example: when granting
managerprivileges, capture both the previous role and the new role in the auditdetailsfield so compliance can see what changed.
References¶
backend/src/lib/logger.tsbackend/src/lib/audit-logger.tsbackend/src/lib/prisma.tsbackend/src/lib/opa.tsgateway/opa/policies/rbac.rego