Public Beta. Reference implementation only — not a compliance certification, attestation, or audit outcome. Read the full beta disclaimer →

Control template: no sensitive data in logs

A CALM control that flags PRs introducing a log statement (or any added line) containing forbidden field names. Customer-authored; ArchRails enforces it via the constraint engine. No regex maintenance on our end, no opinionated key list — the customer owns the vocabulary.

When to use it

The snippet

Add this controls block to whichever node(s) own the code paths you care about (typically your service node):

{
  "unique-id": "<your-service-node>",
  "node-type": "service",
  "name": "<Service Name>",
  "controls": {
    "no-pii-in-logs": {
      "description": "<Customer-authored description. The framer LLM uses this verbatim when explaining a violation — make it your policy language, not ours.>",
      "requirements": [
        {
          "requirement-url": "https://archrails.io/catalog/req/no-pii-in-logs",
          "config": {
            "control-id":       "no-client-pii",
            "name":             "No client PII in plaintext logs",
            "description":      "Applies to all log statements in <your-service-node>.",
            "forbidden-fields": [
              "email",
              "full_name",
              "ssn",
              "tax_id",
              "postal_address",
              "account_number",
              "card_number"
            ]
          }
        }
      ]
    }
  }
}

Tune forbidden-fields to your actual schema. Common additions by industry:

What ArchRails does

The constraint engine enforces every entry in forbidden-fields as a banned token. When a PR adds a line where any of those field names literally appears (case-insensitive, identifier-boundary match), the engine fires a violation with:

This control fires at both MCP-time (in your agent's IDE before code ships) and PR-time (on the merge gate). Same engine, same verdict.

What it does NOT cover (and what to do instead)

This control matches identifier names, not literal-value patterns. So an SSN-shaped literal hardcoded into a log call (logger.info("test ssn 123-45-6789")) won't be caught unless the field name ssn or similar appears in the same line.

Literal-value detection (SSN format, card-like digit runs, JWT tokens, Bearer headers, PEM blobs) is on the roadmap. Until that ships, secret-scanning tools (Snyk, GitGuardian, TruffleHog) are the recommended complement — ArchRails doesn't try to be a secret scanner.

Why customer-authored beats a hardcoded scanner

Because the forbidden-field list, the violation prose, and the attach points are all yours, the audit trail reads as your policy enforced your way — not as a third-party opinion enforced on you. False-positive tuning is editing your CALM, not filing a vendor ticket. Scope is the nodes you attach it to, not every file in the repo.