ADR-007-F: Three-Layer IRAP Architecture (AWS + Go Proxy + Elixir)¶
Status: Accepted Date: 2026-04-16 Decision Makers: Gautham Chellappa Depends on: ADR-001-F (Elixir), ADR-006-F (Hexagonal ports) Related: ADR-0010 (AU data residency for AI — inherited)
Context¶
Finnest must serve defence clients at OFFICIAL:Sensitive (architected for PROTECTED). The Australian Government Information Security Manual (ISM) provides a recommended list of memory-safe languages. BEAM is not explicitly listed. This is a SHOULD, not a MUST, but creates assessor friction.
The decision: redesign Finnest in an ISM-listed language (months of rework, loses BEAM concurrency), negotiate BEAM acceptance directly (possible but slow and risky), or put an ISM-listed boundary language in front of the Elixir app so the assessor's primary scrutiny focuses on 500 lines of Go rather than 150K+ LOC of Elixir.
Decision¶
Three-layer deployment for IRAP:
LAYER 1: AWS infrastructure (ap-southeast-2, IRAP-assessed)
Dedicated VPC, Multi-AZ RDS, S3 Object Lock, CloudHSM,
CloudWatch, CloudTrail, GuardDuty, Security Hub, WAF.
No peering to commercial; no internet egress except allowlist.
LAYER 2: Security Boundary (Go proxy, ~500 LOC, ISM-listed language)
TLS termination (FIPS cipher suites), request validation,
auth verification (JWT + MFA + FIDO2), classification header injection,
audit logging, rate limiting, W3C traceparent propagation, response filtering.
NO business logic. NO database access. NO state.
LAYER 3: Application (Finnest Elixir, same codebase as commercial)
config/runtime.exs branches to :irap — Bedrock Sydney only,
15-min sessions, FIDO2 mandatory, IP allowlist, restricted integrations,
Microsoft Entra SSO only.
One codebase, dual deployment. The commercial and IRAP deployments run the same Elixir release; behaviour branches on FINNEST_ENV=commercial vs FINNEST_ENV=irap in config/runtime.exs (AR-19).
Sixteen IRAP-specific guardrails (IR-01 through IR-16) enforce the restrictions — see ../10-GUARDRAILS.md §12.
Full architecture detail in ../architecture/irap.md.
Alternatives Considered¶
| Alternative | Rejected because |
|---|---|
| Rewrite Finnest in Go or Rust for IRAP | Loses BEAM concurrency + supervision + hot reload; 6+ months of rework; different codebase for commercial vs IRAP violates single-codebase principle |
| Negotiate BEAM acceptance directly with assessor | Possible but slow and risky; assessor-dependent; if rejected late, months of remediation |
| Put Elixir at the boundary, no proxy | Assessor scrutiny lands on 150K+ LOC of Elixir + BEAM VM; BEAM not ISM-listed is a blocker |
| Node.js or Python boundary proxy | Neither is ISM-listed at the boundary role; defeats the purpose |
| Rust boundary proxy | More complex than needed for 500 LOC of request-handling; Go is simpler, well-audited HTTP server ecosystem |
See ../brainstorms/brainstorm-06-irap-strategy.md for full analysis.
Consequences¶
Positive:
- Assessment surface minimised — AWS already assessed, Go proxy is ~500 LOC auditable in isolation, Elixir inherits the boundary
- ISM-listed language (Go) at the security boundary satisfies the assessor regardless of application language behind
- Pre-assessment in Phase 0 validates the approach before committing to full build ($25K de-risks months of work)
- Feature flags make the IRAP restrictions config, not code fork (AR-19)
- Commercial benefits from IRAP-driven hardening (audit, encryption, access control)
Negative:
- Extra hop adds ~5ms latency
- Go proxy is an additional component to monitor, maintain, and version
- Team must maintain two deployment pipelines (commercial + IRAP CI/CD separate per IR-12)
- Need Go expertise for proxy maintenance (minimal — 500 LOC is tractable)
Risk mitigations:
- Pre-assessment meeting in Phase 0 Week 1-2 validates assessor acceptance before proxy development commits
- Proxy code size capped by design — grows past 1000 LOC triggers review
- Proxy has zero state, zero DB access, zero business logic — reduces blast radius if compromised
- W3C traceparent propagation keeps observability continuous across proxy (Part 7 decision)
Tipping points for re-evaluation:
- ISM adds BEAM to the listed languages — proxy becomes optional (keep for defense-in-depth or remove for simplicity)
- IRAP program fundamentally changes (e.g. post-quantum mandates) — re-architect per new requirements
Relationship to Guardrails¶
Enforces: IR-01 through IR-16 (16 IRAP-specific guardrails), AR-19 (IRAP as config variant), ADR-0010 (AU data residency for AI — inherited).