Skip to main content
Learn

Controls for Non-Functional Requirements

โฑ 3 min read๐ŸŸก Intermediate ยท 30-45 minutesTry in Learning Lab โ†—Edit on GitHub โ†—

Overviewโ€‹

Document security, performance, and compliance requirements using CALM's controls feature to capture non-functional requirements (NFRs).

Learning objectivesโ€‹

By the end of this tutorial, you will:

  • Understand the structure of CALM controls
  • Add architecture-level and node-level controls
  • Distinguish between inline config and external config-url implementations
  • Know which control domains are available (security, compliance, performance, operational)

Prerequisitesโ€‹

Complete the Beginner Tutorials section first. You will need your architectures/ecommerce-platform.json from the Build a Complete Architecture lesson.

Try in Learning Labโ€‹

You can work through this tutorial in your browser with the CALM Learning Lab. There is nothing to install: the lab runs the real CALM engine, and the calm commands this tutorial uses work as they do in the CLI. The lab has no AI assistant, so you write the CALM yourself instead of prompting Copilot.

Open this tutorial in the Learning Lab โ†—

Step-by-Step Guideโ€‹

1. Understand Controlsโ€‹

Controls in CALM consist of:

  • Domain key: Category (e.g., security, compliance, performance, operational)
  • Description: What the control addresses
  • Requirements: Array of requirement specifications with:
    • requirement-url: Reference to a JSON Schema that validates the configuration
    • Plus ONE of:
      • config-url: Link to external configuration, OR
      • config: Inline configuration object

Important: Each requirement MUST specify how it's implemented โ€” either via config-url or inline config. This enforces that controls are not just declared but actually configured.

Controls can be applied at multiple levels:

  • Architecture level: Apply to the entire system
  • Node level: Apply to specific components
  • Relationship level: Apply to specific connections between components
  • Flow level: Apply to business processes and data flows

The examples below use CALM's published control requirement schema. It requires control-id, name, and description. The settings and targets below are illustrative. Validation checks the documented configuration, not whether the running system meets the requirement. Use a more specific schema when you need to constrain settings such as encryption algorithms or latency limits.

2. Add an Architecture-Level Security Controlโ€‹

Open your architectures/ecommerce-platform.json from the Build a Complete Architecture lesson.

Create controls/tls-config.json in your tutorial project with this content:

controls/tls-config.json
{
"$id": "controls/tls-config.json",
"$schema": "https://calm.finos.org/release/1.2/meta/control-requirement.json",
"control-id": "SEC-002",
"name": "TLS minimum version",
"description": "All external connections use TLS 1.3 or later"
}

The $id lets the CLI load this local configuration. Run the validation command from your tutorial project root so that controls/tls-config.json resolves correctly.

Prompt:

Add a controls section at the top level of architectures/ecommerce-platform.json

Add a "security" control with:
- description: "Data encryption and secure communication requirements"
- requirements array with two items:
1. requirement-url: "https://calm.finos.org/release/1.2/meta/control-requirement.json"
config (inline): { "control-id": "SEC-001", "name": "Encryption at rest", "description": "All data stores use AES-256 encryption at rest" }
2. requirement-url: "https://calm.finos.org/release/1.2/meta/control-requirement.json"
config-url: "controls/tls-config.json"

Place it after the metadata section and before nodes.

3. Add an Architecture-Level Performance Controlโ€‹

Prompt:

Add a "performance" control at the architecture level of architectures/ecommerce-platform.json

Add with:
- description: "System-wide performance and scalability requirements"
- requirements array with two items:
1. requirement-url: "https://calm.finos.org/release/1.2/meta/control-requirement.json"
config (inline): { "control-id": "PERF-001", "name": "Response time", "description": "Response latency is at most 200 ms at p99 and 100 ms at p95" }
2. requirement-url: "https://calm.finos.org/release/1.2/meta/control-requirement.json"
config (inline): { "control-id": "PERF-002", "name": "Availability", "description": "The platform targets 99.9% availability" }

Place it alongside the security control in the controls section.

4. Add a Node-Level Compliance Controlโ€‹

Add a control to the payment-service node.

Prompt:

Add a controls section to the payment-service node in architectures/ecommerce-platform.json

Add a "compliance" control with:
- description: "PCI-DSS compliance for payment processing"
- requirements array with one item:
- requirement-url: "https://calm.finos.org/release/1.2/meta/control-requirement.json"
config (inline): { "control-id": "COMP-001", "name": "Payment compliance", "description": "Payment processing must meet PCI-DSS v4.0 requirements" }

5. Add a Node-Level Performance Controlโ€‹

Add a performance control to the api-gateway node.

Prompt:

Add a controls section to the api-gateway node in architectures/ecommerce-platform.json

Add a "performance" control with:
- description: "API Gateway rate limiting and caching requirements"
- requirements array with two items:
1. requirement-url: "https://calm.finos.org/release/1.2/meta/control-requirement.json"
config (inline): { "control-id": "PERF-003", "name": "Rate limiting", "description": "Limit each client to 100 requests per second" }
2. requirement-url: "https://calm.finos.org/release/1.2/meta/control-requirement.json"
config (inline): { "control-id": "PERF-004", "name": "Caching", "description": "Use a default TTL of 300 seconds and private cache control" }

6. Validateโ€‹

calm validate -a architectures/ecommerce-platform.json

The architecture and all seven control requirements should pass validation. If a control fails, check that its configuration has all three required fields and that controls/tls-config.json exists and has its $id.

Now is a good time to use git to snapshot your progress. Stage your changes and commit them with a meaningful message before moving on.

Key conceptsโ€‹

Control Domainsโ€‹

DomainPurposeExample Requirements
securityData protection, access controlEncryption, TLS, authentication
complianceRegulatory adherencePCI-DSS, GDPR, SOC2
performanceNon-functional requirementsSLAs, rate limits, availability
operationalRuntime concernsLogging, monitoring, backup

Inline Config vs Config URLโ€‹

{
"requirements": [
{
"requirement-url": "https://calm.finos.org/release/1.2/meta/control-requirement.json",
"config": { "control-id": "SEC-001", "name": "Encryption at rest", "description": "All data stores use AES-256 encryption at rest" }
},
{
"requirement-url": "https://calm.finos.org/release/1.2/meta/control-requirement.json",
"config-url": "controls/tls-config.json"
}
]
}

This example reuses the TLS configuration file from step 2.

Use inline config for simple, self-contained settings. Use config-url when configuration is managed externally or is too complex to inline.

Multi-Level Controlsโ€‹

Controls can be placed at four levels:

  • Architecture level โ€” system-wide requirements
  • Node level โ€” component-specific requirements
  • Relationship level โ€” connection-specific requirements
  • Flow level โ€” business-process-specific requirements

Next stepsโ€‹

In the next tutorial, you'll model business flows that trace how business processes traverse your architecture!