NIST SP 800-53 Architecture Mapping

On this page

Overview

This document provides a detailed mapping of NIST SP 800-53 Revision 5 security and privacy controls to Canopy’s architecture. It supplements the summary in ATO Readiness & Compliance Matrix.

Controls are assessed against the Moderate baseline, which is appropriate for systems processing PII and benefit eligibility data.

AC — Access Control

Control Requirement Canopy Implementation Status

AC-2

Account Management

Keycloak manages all user accounts. Provisioning, deprovisioning, and role assignment performed through Keycloak admin console. 6 roles defined: applicant, caseworker, eligibility_specialist, supervisor, admin, system.

✓ Implemented

AC-3

Access Enforcement

canopy-auth middleware (AuthLayer) validates JWT on every request. Each route handler specifies minimum required role via Claims::require_caseworker_or_above(), require_admin(), etc.

✓ Implemented

AC-4

Information Flow Enforcement

Program service isolation (ADR-001) — each benefit program has its own database and service. No cross-program data access at the database level. Event bus payload validation (27 restricted fields) prevents PII/FTI leakage between services.

✓ Implemented

AC-6

Least Privilege

Role hierarchy enforces minimum necessary access. Caseworkers cannot access admin functions. Program-specific handlers require program-specific roles. Database credentials are per-service.

✓ Implemented

AC-7

Unsuccessful Logon Attempts

Keycloak brute force detection: account lockout after configurable failed attempts. Configurable lockout duration and permanent lockout threshold.

✓ Configured (Keycloak)

AC-8

System Use Notification

Login page displays system use banner (configurable in Keycloak theme). Warning text loaded from jurisdiction configuration.

✓ Configurable

AC-17

Remote Access

All access is remote (web-based). TLS required on all endpoints (rustls). No direct database access from outside the service mesh.

✓ Implemented

AU — Audit and Accountability

Control Requirement Canopy Implementation Status

AU-2

Event Logging

canopy-security subscribes to all events via RabbitMQ wildcard (#) routing key. Every API operation publishes an event through canopy-mq. Event types cover: authentication, authorization decisions, data access, data modification, eligibility determinations, benefit issuance.

✓ Implemented

AU-3

Content of Audit Records

EventEnvelope struct contains: event_id (UUID), source (service name), event_type (dotted path), payload (JSON), timestamp (UTC), trace_context (OpenTelemetry). User identity extracted from JWT claims.

✓ Implemented

AU-4

Audit Log Storage Capacity

PostgreSQL-backed audit storage with configurable archive management. POST /v1/security/archive enqueues a durable, chunked archive run moving old events to the audit_events_archive table (#1208); the live→archive age threshold is the archive_after_days parameter. Retention itself is archive ∪ live (the archive retains indefinitely; policy lifecycle is #1303).

✓ Implemented

AU-6

Audit Log Review, Analysis, and Reporting

GET /v1/security/events API with pagination, filtering by event type, date range, and source. Export capability for external SIEM integration.

✓ Implemented

AU-9

Protection of Audit Information

SHA-256 hash chain links each audit event to its predecessor. Hash chain is append-only — no UPDATE or DELETE on audit tables. Verification: the chain-v2 checkpointed verifier (#1205, ADR-014 Amendment 9) replaced the full-walk GET /v1/security/verify-chain (deleted) with the unified /v1/security/chain/* namespace — continuous background tail + scrub verification, durable manual verify jobs, per-event attestation, and a latched-breach incident model. The verifiers ship DORMANT until the #1279 cutover: status reports unknown → 503 (fail closed, never a stale green) until activation. FTI-family verification landed in #1206 MR-3 — per-family tasks serving family=fti&service=…, same dormancy, with a latched legacy v1 breach still surfacing as breached/legacy_breach_latched.

◐ Landed dormant (#1205 audit; #1206 MR-3 FTI arm): chain structure + verifiers implemented; activation at #1279

AU-11

Audit Record Retention

Audit records are retained across audit_eventsaudit_events_archive — the #1208 archive mover only moves aged rows between the two tables and the archive retains indefinitely, so AU-11 retention is the union, never shortened by archiving. Data-type floors: FTI 7 years (IRS Pub 1075 AU-11; ADR-004 Amendment 2), HIPAA 6 years (45 CFR §164.530(j)), general 3 years (state records retention schedule). See Data Retention Policy.

✓ Implemented

IA — Identification and Authentication

Control Requirement Canopy Implementation Status

IA-2

Identification and Authentication (Organizational Users)

Keycloak OIDC with RS256 JWT. Users authenticate via username/password through Keycloak login page. JWT issued on successful authentication, validated on every API request.

✓ Implemented

IA-2(1)

Multi-Factor Authentication

Keycloak supports MFA (TOTP, WebAuthn). Configuration is per-deployment. Recommended for all users with access to FTI or PHI.

Configurable (Keycloak)

IA-5

Authenticator Management

Password policy enforced in Keycloak: minimum length, complexity, history, expiration. Bcrypt hashing for stored passwords.

✓ Configured (Keycloak)

IA-8

Identification and Authentication (Non-Organizational Users)

JWKS auto-refresh: JwksProvider fetches Keycloak JWKS hourly and on unknown kid. 30-second debounce prevents hammering during key rotation. Supports dual-key verification window.

✓ Implemented

SC — System and Communications Protection

Control Requirement Canopy Implementation Status

SC-8

Transmission Confidentiality and Integrity

rustls for all HTTP endpoints (OpenSSL banned via cargo-deny). PostgreSQL sslmode=require for all database connections. RabbitMQ supports amqps:// for encrypted message transport.

✓ Implemented

SC-12

Cryptographic Key Establishment and Management

ECDSA P-256 signing keys per program service (ADR-002). VerifyingKeyRegistry supports dual-key rotation (current + previous). Keys loaded from PEM environment variables. Generation via cargo xtask gen-signing-keys.

✓ Implemented

SC-13

Cryptographic Protection

AES-256-GCM for field-level PII encryption (SSN). ECDSA P-256 JWS for determination signing. SHA-256 for audit hash chain. RS256 for JWT validation. All via pure-Rust crates (no OpenSSL).

✓ Implemented

SC-28

Protection of Information at Rest

SSN encrypted with AES-256-GCM at the application layer. Encryption key: CANOPY_ENCRYPTION_KEY (base64, 32 bytes). Additional protection via PostgreSQL TDE recommended for production.

Partial — SSN encrypted; TDE for full coverage

SI — System and Information Integrity

Control Requirement Canopy Implementation Status

SI-2

Flaw Remediation

cargo-deny runs in CI: checks advisories (RustSec), banned crates (OpenSSL), and license compliance. Remediation SLAs: Critical 24h, High 7 business days, Medium 30 days. See Security Operations.

✓ Implemented

SI-3

Malicious Code Protection

GitLab SAST (semgrep) and secret detection in CI pipeline. Container scanning on Docker images. #![forbid(unsafe_code)] on all crates prevents memory safety issues.

✓ Implemented

SI-4

System Monitoring

canopy-security background breach detection: watches for privilege escalation patterns, abnormal access volumes, and FTI access anomalies. Publishes breach_alert events. Health checks (GET /healthz) on all services report database and RabbitMQ status.

✓ Implemented

SI-10

Information Input Validation

sqlx compile-time verified queries prevent SQL injection. Axum extractors validate request bodies. canopy-mq payload validation rejects 27 restricted field names. canopy-store validates upload size and file type, sanitizes filenames against path traversal.

✓ Implemented

CM — Configuration Management

Control Requirement Canopy Implementation Status

CM-2

Baseline Configuration

Docker multi-stage builds with Alpine base. Non-root container user. Read-only root filesystem. All configuration via environment variables (no config files in containers).

✓ Implemented

CM-6

Configuration Settings

All settings loaded at startup via ServiceSettings::load(). No runtime configuration changes. Environment variables documented in Configuration Reference.

✓ Implemented

CM-7

Least Functionality

Minimal Alpine containers. Only required ports exposed. No shell in production images. cargo-deny bans unnecessary dependencies.

✓ Implemented

MP — Media Protection

Control Requirement Canopy Implementation Status

MP-4

Media Storage

S3-compatible object storage (Garage in dev, AWS S3/MinIO in production) with versioning for notice PDFs. Access via canopy-store with authentication.

✓ Implemented

MP-5

Media Transport

All object storage access via HTTPS. Internal presigned URLs for PDF delivery. No direct S3 endpoint exposure to users.

✓ Implemented

PE — Physical and Environmental Protection

Physical and environmental controls are the responsibility of the hosting provider (cloud or on-premises). Canopy’s architectural contribution is stateless services that can run in any compliant facility.

PL — Planning

Control Requirement Canopy Implementation Status

PL-8

Security and Privacy Architectures

10 Architecture Decision Records (ADRs) document security-relevant design decisions. ADR-001 (isolation), ADR-002 (signing), ADR-004 (data tenancy) are the primary security architecture documents.

✓ Documented

RA — Risk Assessment

Control Requirement Canopy Implementation Status

RA-5

Vulnerability Monitoring and Scanning

cargo-deny (advisories + bans) in CI. GitLab SAST + secret detection + container scanning. Dependency updates tracked via cargo-audit suppression for known transitive issues (documented in deny.toml).

✓ Implemented

Edit this page · default