docs(architecture): Layer 6 — C4 Container (seven containers)#173
Conversation
|
Warning Review limit reached
More reviews will be available in 16 minutes and 35 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
WalkthroughAdds a draft C4 container-level architecture document and a canonical Mermaid container diagram for OCU, defining seven runnable containers, their responsibilities, named token/protocol boundary crossings, deployment "minimal vs full" shelves, internal security invariants, and two tracked open questions. ChangesC4 Container Architecture
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
docs/architecture/05-c4-container.md (1)
54-54: 💤 Low valueClarify the statement about external actors.
The text states "this view does not redraw them [external actors]," but the diagram explicitly renders PEER, UP, and SINK (and the canonical .mmd also includes OPER). Consider rephrasing to clarify that external actors are shown for context but their detailed contracts are defined in the referenced Layer 3 document.
📝 Suggested clarification
-Canonical source: [`diagrams/c4-container.mmd`](diagrams/c4-container.mmd). Edge labels name the protocol or token class that crosses; `1..N` marks the per-session container. The four Agent-Execution containers fan into the Audit pipeline over one Published Language (OCSF) — drawn as four edges, one label. External actors and their contracts are in [`03-c4-context.md`](03-c4-context.md) §4; this view does not redraw them. +Canonical source: [`diagrams/c4-container.mmd`](diagrams/c4-container.mmd). Edge labels name the protocol or token class that crosses; `1..N` marks the per-session container. The four Agent-Execution containers fan into the Audit pipeline over one Published Language (OCSF) — drawn as four edges, one label. External actors are shown for orientation; their detailed contracts are defined in [`03-c4-context.md`](03-c4-context.md) §4.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/architecture/05-c4-container.md` at line 54, Update the sentence that currently reads "this view does not redraw them" to clarify that external actors (PEER, UP, SINK, and OPER as shown in diagrams/c4-container.mmd) are rendered only for contextual reference while their detailed contracts remain defined in 03-c4-context.md §4; change the wording to something like "External actors (PEER, UP, SINK, and OPER) are shown here for context, but their detailed contracts are defined in 03-c4-context.md §4" so readers know the diagram includes actors visually but the authoritative contract information lives in the Layer 3 document.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/architecture/05-c4-container.md`:
- Around line 24-52: The Mermaid diagram is missing the Operator actor and its
PAM-JIT edge; add an OPER node (label like "Operator / PAM-JIT human") to the
flowchart and the edge OPER -->|"PAM-JIT credential"| CP so the diagram matches
the canonical diagram (ensure the new OPER node uses the same styling pattern as
other actors like PEER/UP/SINK and place the edge pointing to CP).
---
Nitpick comments:
In `@docs/architecture/05-c4-container.md`:
- Line 54: Update the sentence that currently reads "this view does not redraw
them" to clarify that external actors (PEER, UP, SINK, and OPER as shown in
diagrams/c4-container.mmd) are rendered only for contextual reference while
their detailed contracts remain defined in 03-c4-context.md §4; change the
wording to something like "External actors (PEER, UP, SINK, and OPER) are shown
here for context, but their detailed contracts are defined in 03-c4-context.md
§4" so readers know the diagram includes actors visually but the authoritative
contract information lives in the Layer 3 document.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 0980f265-62df-4c44-b20a-3d6c10ec69e3
📒 Files selected for processing (2)
docs/architecture/05-c4-container.mddocs/architecture/diagrams/c4-container.mmd
…le (#177) * docs(architecture): reconcile credential model — strict Anthropic style The canon carried an internally-contradictory credential model: most rows said "broker issues a scoped-JWT into the guest, guest presents it" while NFR-SEC-30 already said "broker terminates outbound TLS". The guest-token framing was never the intent. Converge everything to the strict model confirmed against Anthropic's process_api / egress design: - The guest holds NO upstream credential. It sends an unauthenticated request; the Egress trust-edge attaches the upstream authorization on the outbound leg, fetched from host-side Credential custody. - "Credential broker" → "Credential custody" (host-side store, rotation, delegated STS). Injection folds into the Egress trust-edge. Custody has no guest-facing interface. - Token taxonomy: the guest holds only the Session JWT (session identity, ≤4h, CP→guest). The ≤15min lease is held by the edge (custody credential lease), never the guest. "Egress JWT" → "Session JWT" everywhere. - Injection requires the edge to originate the upstream connection (L7 / MITM mode); transparent pass-through cannot inject. Cert-pinning / client-mTLS / DPoP upstreams tracked at #176. Touches: NFR-SEC-23/25/27/29/30/31 + token taxonomy + SEC-10/11 rename; Layer 3 §2/§3/§5 diagram/§7 revoke/§8/§11; Layer 4 §2/§4; Layer 5 zone names + context-map vocab + open question; glossary entries. The five containers do not change — custody and edge stay two boxes (custody ≠ enforcement). Layer 6 (PR #173) reconciled separately on its branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(architecture): soften §8 token-table cross-claim (RC-01) Scope-consistency review (6/6 PASS, 2 nits): the §8 table claimed to match the NFR token table "verbatim", but the two now differ in column header (Consumer vs Holder) after the rewrite. Claim the three classes / scopes / TTLs match, not the literal layout. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(architecture): drop negative-restatement (doc-slop-reviewer) Three spots stated the "guest holds no upstream credential" invariant two or three times in one passage. Keep the single load-bearing negative, drop the restatements: custody glossary ("custody issues no token to the guest"), egress-edge fail-closed ("never bypassed"), token-table ("not anything the guest holds —"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(architecture): clarify revoke timeline ≤1/≤5/≤15 (CodeRabbit) The rewrite left two revoke numbers reading as a conflict (≤5 min propagation vs ≤15 min lease survival). State the three bounds smallest-first: custody revokes the lease ≤1 min (NFR-SEC-29); denylist propagates ≤5 min (NFR-SEC-04); a non-revoked lease self-expires at its ≤15 min TTL. An explicit revoke cuts upstream access within ≤5 min — the 15-min TTL is only the ceiling for a session never revoked. Resolves both CodeRabbit nits. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(architecture): clarify token rotation, injection mode, revoke SLAs - NFR-SEC-10: the ≤4h is a per-token TTL, not a session cap. While a session is active the Control plane rotates the token before expiry (a stolen token dies in ≤4h); session length is not bounded by the TTL. A long human session (multi-hour investigation) is not interrupted. Drop the undefined "session-max"; a hard session cap, if any, is a policy tracked at #178. - NFR-SEC-29 (CodeRabbit): ≤1 min revocation is custody-internal — a tighter subset of the ≤5 min platform-wide target (NFR-SEC-04). State the relation. - Layer 3 zone 4 (CodeRabbit): qualify that upstream-auth injection is MITM-inspecting mode only; transparent pass-through cannot inject (§7). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(architecture): anchor session limits to regulators; demote token TTL The ≤4h session-JWT TTL was an unsourced number that conflated three distinct limits. Research (PCI-DSS 4.0, NIST SP 800-63B-4) separates them; we align to AAL3 (privileged automation in a bank perimeter): - NFR-SEC-10: session JWT TTL ≤4h → ≤60min, reframed as an anti-replay window (engineering bound, no regulatory citation), rotated while the session runs. - NFR-SEC-40 (new): idle / inactivity timeout ≤15min — PCI-DSS 4.0 Req 8.2.8 + NIST 800-63B-4 §2.3.3 (AAL3). This is the number a bank auditor looks for. - NFR-SEC-41 (new): absolute session lifetime ≤12h — NIST 800-63B-4 §2.3.3 (AAL3 SHALL). Default off on the minimal shelf, customer-tunable on the full shelf. Closes #178 with a sourced number instead of "if any". Token TTL ≠ idle ≠ absolute: the token rotates under both session limits; session length is bounded by SEC-40/41, not by the token TTL. Updated token taxonomy table, Layer 3 §5/§8 + diagram, glossary Session JWT entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(architecture): cut IdP-independence restatement (doc-slop-reviewer) §7 revoke paragraph stated IdP-independence three times. Keep the opening claim and the closing rationale ("that is why ≤5 min revoke holds even during an IdP outage"); drop the bare middle restatement. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(architecture): generalize MCP allow-list → egress allow-list "MCP allow-list" mixed abstraction levels — it named a private case (one destination type) where the general control (egress allow-list, deny-by- default) was never stated. An MCP server, LLM API, object store, or internal API is one allow-listed destination, not its own enforcement mechanism. - NFR-SEC-08: "MCP allow-list enforcement" → "Egress allow-list" (customer declares reachable destinations; deny-by-default; destination type is not a separate control). - Layer 3 zone 4 + .mmd: same generalization. How a corporate environment authors these egress rules (rule format / standard) is deferred to the egress-proxy component spec + a separate research pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(architecture): finish MCP allow-list → egress allow-list (2 stragglers) bounded-contexts §3 and the §02 long-form-scenario list still named the private case. Generalize both. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(architecture): fix two more abstraction-substitution defects + skill supply-chain NFR Abstraction-substitution sweep (the MCP-allow-list defect class) found two more embarrassing instances; both fixed: - NFR-SEC-17 named "Egress posture (sandbox trust tier)" — but it is the enforcement mechanism of the NFR-SEC-08 allow-list, and "Egress posture" collides with the glossary/NFR-FLEX-15 term (transparent vs MITM). Renamed to "Egress allow-list enforcement mechanism" + cross-link SEC-08↔SEC-17. - NFR-SEC-05 named "MITM-friendly egress" — but it anchors the whole Egress zone and MITM is the opt-in mode, not the default. Renamed "Single forward-proxy egress (customer-CA injectable; MITM-inspecting opt-in)". - primitives-backlog: same two renames. Also: NFR-SEC-42 (new, v2/tbd) — skill-registry supply chain (author-uploaded, server-signed, provenance-tracked, signature-verified at attach), pairs with SkillProvider NFR-SEC-24; tracks #179. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(architecture): drop last 'MCP allow-list' straggler in PROCESS.md example Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cut five abstract containers (role names only) along the Layer 3 trust zones and Layer 5 bounded contexts: Control plane / MCP server, Session sandbox, Credential broker, Egress trust-edge proxy, Audit pipeline. - §1 distinguishes container (runnable unit) from zone (deploy slice) and bounded context (domain slice); Agent Execution is one context realized as four containers. - §2 diagram + canonical c4-container.mmd; edge labels name protocol/token class, 1..N marks the per-session sandbox, audit fan-in over OCSF. - §3 one-line responsibility per container; guest agent = PID 1 stays inside the sandbox (not a sixth container). - §4 internal boundaries; sandbox has no direct path to network or secret. - §5 minimal vs full shelf substitutions (same five containers). Tech choices deferred to Layer 10 component specs. No technology names in the diagram or prose, per CLAUDE.md Diagrams rule. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Scope-consistency review (zero blockers, 7 invariants hold): - SC-10: inline diagram dropped the Operator actor + PAM-JIT edge that the canonical .mmd carries; add OPER node + edge so the two agree. - SC-07: broker edge label scoped-JWT → Broker scoped-JWT, matching the canonical token-class name in 02-trust-boundaries.md §8. - SC-05: §5 shelf table now points to §7–§8 as the owning source instead of re-deciding egress-mode / identity-floor detail. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bit) The §2 diagram now renders external actors, so "this view does not redraw them" misread. Reword: actors drawn for orientation, contracts in L4 §4. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gsd-code-reviewer (1 blocker, 3 warnings, 2 nits), doc-slop-reviewer (clean), gsd-plan-checker (achieves goal): - CR-01 (blocker): §6 open questions linked #168/#169, which track Layer 5 *bounded-context* questions, not the *container/deployment* questions asked here. Open #174 (sandbox container split) + #175 (broker cardinality) and relink. - CR-02: §5 prose vs .mmd shelf convention conflicted. Containers are identical on both shelves → diagram is shelf-agnostic; reword .mmd convention comment to match. - CR-03/04/05: inline §2 diagram had drifted from the canonical .mmd (missing subgraph OCU boundary box, UP vs UPSTREAM id, broker label). Rebuild inline as a faithful render of the .mmd. - CR-06: dropped two "Layer 10" forward references → components/ + PROCESS.md. - slop info: tightened purpose-line audience clause. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…x zones Rewrites the container view to match the current trust-boundary model: six zones, with the Control plane split into an agent-facing MCP gateway and an operator/lifecycle API so the kill-switch is unreachable from the agent path by network policy, not an in-process route guard. The other five zones map 1:1, including the Storage broker as its own container. - Seven containers: MCP gateway, Control / operator API, Credential custody, Storage broker, Session sandbox [1..N], Egress trust-edge proxy, Audit pipeline. Each carries its NFR anchor. - Edges match the token taxonomy: Session JWT bound to container_name (≤60 min, host dials guest), custody credential lease (≤15 min, held by the egress edge), storage-mount handle (filesystem_id). Host-attested control channel, off the guest network. - Storage broker drawn on both legs — the guest mount (inbound) and the broker-signed backend request through the egress edge in allow-list-only mode (outbound); no direct broker-to-backend dial. - §6 compares the decomposition to the industry shape and states where OCU diverges (storage broker as its own container, egress as a credential- injecting chokepoint) for the in-perimeter regulated threat model. - The diagram lives only in diagrams/c4-container.mmd; the doc links it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2a6366b to
2998c60
Compare
…rage NFR, inbound control edges - Egress injection is MITM-mode-only; the minimal-shelf transparent pass-through cannot inject. Diagram + §3 egress row qualify it; the broker's pre-signed leg is allow-list-only, so the edge runs per-destination modes, not one global mode. - Storage broker row anchors NFR-SEC-15 (broker property), not NFR-SEC-31, which enforces prefix isolation at the edge/custody boundary, not in the broker. - §4 adds the two inbound control edges into the Control / operator API — IdP relying-party assertion and the SOAR revoke admin API — so the kill-switch owner's full inbound surface is visible for the threat model. - Drop hardcoded TTLs from the diagram (canonical in §8); 'all six source containers' fan into audit (the pipeline is the sink, not an emitter). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ners, not all) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
The container view of the OCU box that Layer 4 drew as one block — seven containers across the six trust zones.
The Control plane splits into two containers on its interface seam: an agent-facing MCP gateway and an operator/lifecycle API. The kill-switch lives only on the operator API, unreachable from the agent path by network policy — a deploy-time fact, not an in-process route guard. The other five zones map 1:1, including the Storage broker as its own container.
Seven containers: MCP gateway · Control / operator API · Credential custody · Storage broker · Session sandbox [1..N] · Egress trust-edge proxy · Audit pipeline.
Faithful to the current model
container_name(≤60 min, host dials guest), custody credential lease (≤15 min, held by the egress edge — never the guest), storage-mount handle (filesystem_id).Notes
diagrams/c4-container.mmd; the doc links it (no inline duplicate).🤖 Generated with Claude Code
Summary by CodeRabbit