Create your own
Lesson illustration

Constructing a Secure Backend Platform Container Diagram

Good to see you again. In the previous lesson, you treated the Tenant Behavioral Detection Platform as a single black box: it receives tenant Microsoft Entra ID sign-in telemetry, relies on a corporate identity service, and serves tenant administrators, SOC analysts, and platform operators. You also identified the trust changes at those external relationships.

Now we zoom in one level. The aim is to construct a C4 container diagram that makes the platform’s major runtime building blocks, data stores, and inter-process relationships reviewable. The result should be detailed enough for engineering and security review, while remaining far above Rust crates, database tables, Kubernetes objects, and API routes.

For this pilot, the diagram must support a defensible story about tenant-scoped investigation, timely impossible-travel detection, source-health visibility, and recovery from processing failures.


A container is a runtime responsibility, not a Docker image

In C4, a container is an independently executable or separately operated unit within a software system. Common containers include:

  • a browser-based web application;
  • a backend API;
  • a background worker;
  • a message broker or durable event log;
  • a relational database;
  • an object store.

“Container” here does not mean a Linux or OCI container. A Rust API deployed to Kubernetes is a C4 container, but so is a managed PostgreSQL database or a Kafka-compatible event log. Conversely, an Axum router, a Rust crate, a PostgreSQL schema, a Kafka topic, or a Kubernetes deployment is usually too detailed for this view.

The container diagram is where an architecture starts to make operational commitments. It answers questions such as:

  • Which application performs tenant authorization?
  • What isolates ingestion failure from detection processing?
  • Where does investigation state live?
  • Which container interacts with an external identity provider?
  • Which relationships are synchronous API calls, and which are durable asynchronous handoffs?
  • Which technologies and protocols must security and operations teams evaluate?

The C4 container view retains directly connected people and external systems from the context diagram, but replaces the system black box with its internal containers.

Visualising software architecture with the C4 model - Simon Brown, Agile on the Beach 2019

Watch Simon Brown’s “Visualising software architecture with the C4 model” from Agile on the Beach. It gives a compact explanation of the Level 2 container view and the notation discipline that makes a diagram useful in a design review.

Watch the container view to see how a system-context box is decomposed into applications, databases, technologies, and runtime connections. Then watch boxes and lines, focusing on concise descriptions, directional relationships, and labels that state what the relationship actually means.

The supplied Internet Banking System example illustrates the change in zoom particularly well.

A C4 container diagram that retains the banking customer and external email and core-banking systems, while decomposing the Internet Banking System into static content, a browser UI, a backend application, a statement store, and a database. The labeled links describe runtime interactions and protocols rather than code-level calls.

Notice three useful properties:

  1. Every internal box has a responsibility. “Backend” is still broad, but it is at least named as an application and described as providing JSON-over-HTTP functionality.
  2. Technology is visible. The UI, backend, relational database, and object store can be assessed by engineers and operators without pretending that a deployment diagram has already been produced.
  3. The diagram remains selective. It does not show classes, endpoints, cache keys, database indexes, pods, or every cloud service.

For a cybersecurity platform, the same restraint matters. A diagram overloaded with security-product jargon often conceals the actual data paths that need review.


The notation contract: make the diagram stand alone

A reviewer should be able to read your diagram without listening to a five-minute explanation from its author. That requires consistent element types, short responsibility descriptions, explicit technology choices, directional relationship labels, and a legend.

Notation | C4 model

Read the C4 model’s “Notation” guidance. It is a concise standard for making diagrams understandable outside the meeting in which they were created.

In the “Elements” subsection, begin a few sentences before the technology requirement and read through the end of that subsection. Then read the full “Relationships” subsection, paying particular attention to relationship direction, meaningful labels, and protocol annotations. Finish with “Diagram key/legend”; use it as a checklist for the diagram you construct below.

Apply these conventions to this course’s diagrams:

Diagram elementWhat to includeExample
Container nameA stable responsibility-oriented nameTelemetry Connector
TypeExplicitly identify it as a container, person, or software systemContainer: Rust background worker
DescriptionOne short statement of responsibility“Collects, validates, and normalizes tenant audit events.”
TechnologyPrimary implementation or storage technologyRust/Tokio, PostgreSQL, Kafka-compatible event log
Relationship labelAn action and meaningful data exchanged“Publishes validated normalized events”
ProtocolThe relevant runtime mechanismHTTPS, OIDC, PostgreSQL/TLS, Kafka TLS/SASL

A relationship should read naturally from source to destination. For example:

The Telemetry Connector publishes validated normalized events to the Durable Event Log using Kafka TLS/SASL.

That is much more useful than “Connector uses Kafka.”

What belongs outside this diagram

Do not place the following on this container diagram unless one has become a separately operated runtime system that materially changes the story:

  • Rust modules, crates, traits, handlers, or middleware;
  • individual API endpoints;
  • database schemas, tables, row-level-security policies, or indexes;
  • Kafka topics, consumer groups, offsets, or dead-letter policies;
  • Kubernetes pods, namespaces, node pools, virtual networks, or IAM roles;
  • cryptographic primitives and individual firewall rules;
  • CI/CD pipelines and infrastructure-provisioning workflows.

Those details will matter later. They are simply different views: component diagrams, data-flow diagrams, deployment diagrams, and implementation documentation.


Derive containers from responsibilities, failure boundaries, and data ownership

The context diagram identified the platform’s external relationships. The next step is not to invent a microservice for every noun in the product brief. Instead, identify responsibilities that need separate lifecycle, scaling, failure isolation, or data-management treatment.

For the behavioral-detection pilot, the important forces are:

  • Tenant-facing investigation: analysts and administrators need a controlled, tenant-scoped interface.
  • External telemetry collection: Entra integration has source-specific credentials, rate limits, failure modes, and health status.
  • Asynchronous detection: event receipt must not wait for impossible-travel evaluation.
  • Recovery: a worker outage should not silently discard accepted telemetry.
  • Evidence and case data: analysts need alert summaries and supporting event evidence.
  • Federated workforce identity: the platform trusts an external identity issuer but must still validate tokens and enforce its own authorization decisions.

A coherent pilot decomposition is below.

ContainerResponsibilityTechnologyWhy it is separate
Web ConsoleLets tenant administrators configure sources and lets SOC analysts investigate and close alerts.TypeScript single-page applicationBrowser-facing user experience evolves independently of backend processing.
Investigation and Control APIValidates access tokens, applies tenant-aware authorization, serves alert and configuration workflows, and records privileged actions.Rust, Axum, JSON over HTTPSIt is the primary policy-enforcement point for tenant-facing API requests.
Telemetry ConnectorCollects tenant-scoped Entra sign-in events, validates and normalizes them, records source health, and publishes accepted events.Rust, Tokio background workerIntegration behavior, credentials, source throttling, and retry logic should not be coupled to analyst requests.
Durable Event LogBuffers normalized security events durably between ingestion and detection.Kafka-compatible event logIt decouples ingestion availability from detection throughput and enables replay after worker failure.
Detection WorkerConsumes normalized events, maintains the state needed for impossible-travel evaluation, and creates alert summaries.Rust, Tokio background workerIt scales and fails independently from the API and connector.
Investigation StoreStores tenant configuration, connector cursors and health, detection state, alert summaries, cases, and disposition history.PostgreSQLThese records require transactional updates and are queried by the investigation workflow.
Evidence ArchiveRetains source records and normalized event evidence subject to tenant-scoped access and retention controls.S3-compatible object storageEvidence can grow much faster than operational case data and has a different storage and lifecycle profile.

This is not a claim that seven deployables are always the correct production architecture. It is a reviewable baseline for the current pilot. In an early implementation, the Connector and Detection Worker could run from one Rust workspace or even one deployable process, while still being represented separately if their operational responsibilities are intentionally distinct. If that decision is temporary, document it as such.

Security implications should be visible in responsibilities

A secure diagram does not become secure by adding padlock icons. Instead, responsibilities should expose where security-relevant behavior occurs.

  • The Web Console is an untrusted browser execution environment. It presents user workflows; it does not establish tenant authorization merely because a user signed in.
  • The Investigation and Control API validates security-relevant token claims and makes authorization decisions for tenant-scoped data access. It must propagate tenant context deliberately to every downstream query and object lookup.
  • The Telemetry Connector treats source data as untrusted input even when it arrives from an authenticated tenant integration. It must handle malformed, duplicated, delayed, and unexpectedly high-volume events.
  • The Durable Event Log is a resilience boundary, not an authorization boundary. Access controls and encrypted transport still matter.
  • The Detection Worker must make alert creation safe under retries and restarts; later lessons will formalize idempotency and processing semantics.
  • The Investigation Store and Evidence Archive must prevent cross-tenant retrieval. The exact PostgreSQL isolation pattern and object-access policy are deliberate future design decisions, not details to hide.

A useful rule is:

If a container receives data, makes an access decision, persists tenant data, or crosses into a different trust domain, its description should make that responsibility apparent.


Construct the pilot container diagram

The following diagram specification makes one explicit integration decision: the platform collects Microsoft Entra ID sign-in records through its connector, rather than accepting inbound delivery. This is a valid current design choice, not an unavoidable fact of the product. If discovery later establishes that push delivery is preferable, the relationship and connector behavior should change accordingly.

The corporate identity service and Microsoft Entra ID remain external because they were external in the context diagram. The platform depends on them but does not own their implementation. The storage and event-log containers are inside the platform boundary because they are part of the runtime capability the platform must operate and secure, even if implemented with managed cloud services.

Relationship inventory

Before drawing, define the meaningful runtime relationships. This keeps the visual diagram from becoming a collection of unlabeled lines.

SourceDestinationRelationship label and protocolArchitectural significance
SOC analyst or tenant administratorWeb ConsoleInvestigates alerts or configures source access, HTTPSKeeps user interaction on the browser-facing container.
Web ConsoleCorporate Identity ServiceAuthenticates workforce user, OIDCMakes the federation boundary visible.
Web ConsoleInvestigation and Control APIReads tenant alerts and records dispositions, HTTPS/JSONThe API receives client-controlled requests and bearer tokens.
Investigation and Control APICorporate Identity ServiceObtains issuer signing metadata, HTTPSToken trust is grounded in an external issuer.
Investigation and Control APIInvestigation StoreReads and writes configuration, cases, and audit records, PostgreSQL/TLSTenant authorization must constrain these queries.
Investigation and Control APIEvidence ArchiveRetrieves authorized investigation evidence, HTTPSObject retrieval must remain tenant-scoped.
Telemetry ConnectorMicrosoft Entra IDCollects tenant sign-in audit events, HTTPS/Microsoft GraphExposes the source dependency and collection mechanism.
Telemetry ConnectorDurable Event LogPublishes validated normalized events, Kafka TLS/SASLSeparates event acceptance from detection.
Telemetry ConnectorInvestigation StoreReads connector configuration and records health cursor, PostgreSQL/TLSSupports health monitoring and restart continuity.
Telemetry ConnectorEvidence ArchiveArchives source event evidence, HTTPSPreserves investigation material separately from operational state.
Detection WorkerDurable Event LogConsumes normalized events, Kafka TLS/SASLMakes asynchronous processing explicit.
Detection WorkerInvestigation StoreMaintains detection state and writes alert summaries, PostgreSQL/TLSConnects detection decisions to analyst-visible state.
Platform operatorWeb ConsoleViews connector health and operational status, HTTPSTreats operational access as a distinct privileged workflow.

The table does not replace a diagram. It is the diagram’s semantic contract: every line in the rendered view should correspond to a relationship worth reviewing.

Diagram-as-code baseline

For a principal-level architecture artifact, keep the source under version control with the architecture brief. Structurizr DSL is one practical option because it separates the architecture model from its rendered views.

Tutorial | Structurizr

Read the Structurizr tutorial’s sections on defining containers and rendering a container view. The goal is not to memorize the DSL; it is to see how a version-controlled model can generate consistent context and container diagrams.

In “2. Containers,” read the container declaration example, including the two code samples that define a container view. Then read “4. View expressions” and inspect the include examples. Notice how a container view retains relevant external people and systems while keeping the system under design as its scope.

Here is a compact starting model for the pilot. It deliberately shows containers and their runtime relationships, rather than attempting to encode future implementation detail.

workspace "Tenant Behavioral Detection Platform" "C4 container model for the pilot" {
    !identifiers hierarchical

    model {
        analyst = person "SOC Analyst" "Investigates tenant-scoped behavioral alerts."
        administrator = person "Tenant Administrator" "Configures tenant telemetry access."
        operator = person "Platform Operator" "Monitors integration health and incident state."

        identity = softwareSystem "Corporate Identity Service" "External workforce identity provider."
        entra = softwareSystem "Microsoft Entra ID" "External tenant sign-in audit source."

        platform = softwareSystem "Tenant Behavioral Detection Platform" {
            console = container "Web Console" "Provides tenant administration, investigation, and operational views." "TypeScript SPA"

            api = container "Investigation and Control API" "Validates tokens, enforces tenant-aware authorization, and serves configuration and investigation workflows." "Rust/Axum"

            connector = container "Telemetry Connector" "Collects, validates, and normalizes tenant sign-in events; records integration health." "Rust/Tokio worker"

            eventLog = container "Durable Event Log" "Durably buffers normalized security events between ingestion and detection." "Kafka-compatible event log"

            detector = container "Detection Worker" "Evaluates impossible-travel behavior and creates alert summaries." "Rust/Tokio worker"

            store = container "Investigation Store" "Stores tenant configuration, connector cursors, detection state, alerts, cases, and audit records." "PostgreSQL"

            evidence = container "Evidence Archive" "Retains source records and normalized evidence under retention controls." "S3-compatible object storage"
        }

        analyst -> platform.console "Investigates tenant alerts" "HTTPS"
        administrator -> platform.console "Configures source access" "HTTPS"
        operator -> platform.console "Views integration health" "HTTPS"

        platform.console -> identity "Authenticates workforce user" "OIDC"
        platform.console -> platform.api "Reads alerts and records dispositions" "HTTPS/JSON"

        platform.api -> identity "Obtains issuer signing metadata" "HTTPS"
        platform.api -> platform.store "Reads and writes cases, configuration, and audit records" "PostgreSQL/TLS"
        platform.api -> platform.evidence "Retrieves authorized evidence" "HTTPS"

        platform.connector -> entra "Collects tenant sign-in audit events" "HTTPS/Microsoft Graph"
        platform.connector -> platform.eventLog "Publishes validated normalized events" "Kafka TLS/SASL"
        platform.connector -> platform.store "Reads configuration and records source-health cursor" "PostgreSQL/TLS"
        platform.connector -> platform.evidence "Archives source event evidence" "HTTPS"

        platform.detector -> platform.eventLog "Consumes normalized events" "Kafka TLS/SASL"
        platform.detector -> platform.store "Maintains detection state and writes alert summaries" "PostgreSQL/TLS"
    }

    views {
        container platform "secure-backend-containers" {
            include *
            autolayout tb
        }
    }
}

When rendered, add a legend with at least these meanings:

  • System boundary: the Tenant Behavioral Detection Platform.
  • Internal boxes: C4 containers operated as part of the platform capability.
  • External boxes: people or software systems outside the platform boundary.
  • Directed lines: runtime dependency or primary data-flow direction.
  • Technology annotations: primary implementation, data-store, or protocol choice.

Do not use color as the only way to distinguish trust or container type. A diagram should still be understandable when printed in grayscale or viewed by someone unfamiliar with its original tool.


Review the diagram against the quality scenarios

A container diagram is useful when it can be challenged against explicit requirements. For the pilot, use the quality scenarios established earlier to test whether the decomposition has a reason to exist.

Quality concernContainers involvedWhat the diagram should make reviewable
Tenant isolationWeb Console, API, Investigation Store, Evidence ArchiveThe browser is not trusted to enforce tenant scope; the API is the authorization point, and all persistence paths carry tenant-scoped data.
Timely detectionConnector, Durable Event Log, Detection WorkerIngestion and scoring are decoupled, allowing workers to scale or recover independently.
Recovery from processing failureDurable Event Log, Detection Worker, Investigation StoreAccepted events can remain available for reprocessing, while state and alert records survive worker restarts.
Silent telemetry sourceConnector, Investigation Store, Web ConsoleThe connector records health and cursor state, and an operational user can observe source health through an explicit path.
Federated workforce accessWeb Console, API, Corporate Identity ServiceAuthentication depends on the identity service, but platform authorization remains inside the platform boundary.

The diagram does not prove these properties. For example, showing PostgreSQL does not prove row-level tenant isolation, and showing a Kafka-compatible event log does not prove exactly-once alert creation. It does, however, identify the containers where the proof obligations belong.

Assumptions to record next to the diagram

A polished diagram should not hide unresolved decisions. Record these as assumptions or open decisions:

  1. Telemetry collection: The pilot pulls sign-in events from Microsoft Entra ID using Microsoft Graph. Confirm tenant permissions, rate limits, pagination, and collection latency.
  2. Event processing: The event log provides the durability and replay behavior required for the pilot. Delivery semantics, partitioning, and idempotent processing remain to be specified.
  3. Tenant storage model: The initial Investigation Store is shared PostgreSQL. The exact isolation mechanism, including database roles and possible row-level security, remains a security-design decision.
  4. Evidence retention: The retention period, deletion obligations, and access model for evidence have not yet been fixed.
  5. Operational access: Platform operators can inspect source health without unrestricted access to tenant evidence. The precise privileged-access workflow remains to be designed.
  6. Secret handling: Connector and data-store credentials are not represented as a secret-store container in this view. If an external secret-management system becomes a material runtime dependency, add it as an external system and show its relationship to the affected containers.

Studio workflow: produce your version

Use the baseline model as a starting point, not an answer to copy mechanically.

  1. Create a diagram source file in the same repository as the pilot architecture brief.
  2. Render a container view with the system boundary, the seven internal containers, the three human roles, and the two external systems.
  3. Add the responsibility and technology text to every internal container.
  4. Ensure every relationship has one direction, an action-oriented label, and a protocol where containers communicate.
  5. Put the six assumptions beside the diagram or in a linked decision log.
  6. Conduct a short review by reading every relationship aloud as a sentence. If a sentence sounds vague, replace labels such as “uses,” “connects,” or “integrates with” with the actual action and data involved.
  7. Remove anything that belongs to a component, deployment, or data-flow diagram rather than a container view.

A final principal-level check is to ask whether a new engineer could identify the platform’s main data-bearing containers, external trust dependencies, and operational failure boundaries in under two minutes. If not, simplify the visual layout or sharpen the descriptions before adding more detail.


Key takeaways

A C4 container diagram decomposes the context-level system into its major applications, workers, data stores, and runtime relationships. It is not a Docker diagram, class diagram, deployment diagram, or threat-model DFD.

For the behavioral-detection pilot, a useful baseline includes:

  • a browser-based Web Console;
  • a Rust Investigation and Control API;
  • a Rust Telemetry Connector;
  • a durable event log;
  • a Rust Detection Worker;
  • PostgreSQL for operational and investigation state;
  • object storage for retained evidence.

The essential design narrative is that tenant-facing authorization lives at the API boundary, source-specific ingestion is isolated in a connector, durable buffering separates ingestion from detection, and case data and evidence have distinct storage responsibilities.

Next, you will quantify this design by estimating peak throughput, storage growth, and bandwidth from stated workload assumptions. That capacity model will test whether the container responsibilities and technology choices remain plausible under normal operation and attack traffic.

Can't find a good explanation? Sign up and we'll make it for you

Sign up