Fedramp Compliance Patterns

Production-grade guide to fedramp compliance patterns covering architecture patterns, implementation strategies, testing approaches, and operational best practices for enterprise engineering teams.

Fedramp compliance patterns are standardized approaches to achieving and maintaining Federal Risk and Authorization Management (FedRAMP) certification for cloud services. These patterns apply when a cloud provider or agency must demonstrate that their system meets the security and operational requirements defined by the U.S. federal government, particularly for systems handling controlled unclassified information (CUI) and higher impact levels. They are essential during initial authorization (A&A), continuous monitoring, and re-authorization cycles, where consistency, auditability, and automation are non-negotiable.

Establishing a FedRAMP-Ready System

A FedRAMP-ready system begins with a foundational configuration that aligns with the FedRAMP Security Baseline, a set of controls derived from NIST SP 800-53. The process starts with defining the system boundary and identifying the *Security Control Baseline* (Low, Moderate, or High) in the System Security Plan (SSP).

The SSP is a living document, maintained in a version-controlled repository using Git. It includes:

Each CI is tracked in a YAML-formatted control-implementation.yaml file, with entries like:

- control-id: AC-2
  control-name: Account Management
  description: "User accounts are created, modified, and disabled according to policy."
  implementation: |
    - Users are provisioned via the Identity Provider (IdP) using SAML 2.0.
    - Account lifecycle is governed by a workflow in the HR system.
    - Account status is synchronized to the cloud platform daily.
  status: "implemented"
  evidence: 
    - "https://evidence.example.com/ac-2/2024-03-15.pdf"
    - "https://api.example.com/v1/audits?control=AC-2&date=2024-03-15"
  owner: "[email protected]"

The system boundary is defined in a system-boundary.json file:

{
  "system-name": "Customer Engagement Platform",
  "system-id": "CEP-2024-001",
  "system-type": "IaaS",
  "components": [
    {
      "name": "Web Application",
      "type": "Application",
      "ip-range": "10.0.0.0/16",
      "services": [
        "HTTPS (443)",
        "SFTP (22)"
      ],
      "data-flow": [
        {
          "source": "Customer Portal",
          "destination": "Backend API",
          "protocol": "HTTPS",
          "data-classification": "CUI"
        }
      ]
    }
  ],
  "security-requirements": [
    "NIST SP 800-53 Rev. 4",
    "FedRAMP AC-1, AC-2, AC-3, SI-2"
  ]
}

A system must be validated against this boundary via a System Security Plan (SSP) and a Security Assessment Report (SAR). The SAR is generated by scanning the system with a tool like OpenSCAP and submitting results in an XCCDF (Extensible Configuration Checklist Description Format) report.


sudo oscap xccdf eval \
  --profile fedramp-moderate \
  --report report.html \
  --results results.xml \
  --results-arf results.arf \
  /usr/share/openscap/xccdf/fedramp-moderate.xml \
  /etc/scap/controls.yaml

The results.arf file is an ARF (Assessment Result Format) file, a standardized XML format for security assessment results. It is ingested into the FedRAMP Continuous Monitoring (CM) system.

Common Failure: Misaligned Control Implementation

A frequent silent failure is the mismatch between the SSP and actual system behavior. The SSP may list "AC-2 implemented" but the system does not log account creation events. The audit trail shows that HR updates are not synchronized to the cloud. This discrepancy is detected only during a third-party assessment.

To catch this, a control validation pipeline runs weekly:

# .github/workflows/validate-controls.yml
name: FedRAMP Control Validation
on:
  schedule:
    - cron: '0 2 * * 0'  # Every Sunday at 2 AM UTC

jobs:
  validate-controls:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install OpenSCAP
        run: |
          sudo apt update
          sudo apt install -y openscap-scanner
      - name: Run FedRAMP Scan
        run: |
          sudo oscap xccdf eval \
            --profile fedramp-moderate \
            --report report.html \
            --results results.xml \
            --results-arf results.arf \
            /usr/share/openscap/xccdf/fedramp-moderate.xml \
            /etc/scap/controls.yaml
      - name: Upload ARF to CM System
        run: |
          curl -X POST \
            -H "Authorization: Bearer $CM_API_TOKEN" \
            -H "Content-Type: application/xml" \
            --data-binary @results.arf \
            https://cm.fedramp.gov/api/assessments
      - name: Create SAR Entry
        run: |
          python3 -c '
import json
with open("results.xml") as f:
    results = json.load(f)
with open("sar-template.json") as f:
    template = json.load(f)
template["assessment-date"] = results["date"]
template["results"] = results
with open("sar.json", "w") as f:
    json.dump(template, f, indent=2)
          '
      - name: Commit SAR
        run: |
          git add sar.json
          git commit -m "Update SAR with weekly assessment"
          git push

Mapping Controls to Technical Artifacts

Each security control must be linked to technical artifacts: configuration files, logs, audit trails, and automated checks. The mapping is done via control evidence artifacts stored in a content-addressable storage system (e.g., S3 or a Git LFS repository).

For example, the control SI-2 (System and Communications Protection) requires that all system communications are encrypted in transit. The evidence includes:

{
  "control-id": "SI-2",
  "control-name": "System and Communications Protection",
  "evidence": [
    {
      "type": "certificate",
      "file": "certs/lb.example.com.crt",
      "issuer": "Let's Encrypt Authority X3",
      "validity": "2024-01-01T00:00:00Z/2025-01-01T00:00:00Z",
      "key-algorithm": "RSA",
      "key-size": 2048,
      "subject": "CN=lb.example.com"
    },
    {
      "type": "configuration",
      "file": "app/config/tls-config.json",
      "content": {
        "cipher-suites": [
          "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA512",
          "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
        ],
        "protocols": ["TLSv1.3", "TLSv1.2"],
        "client-auth": true,
        "session-timeout": 3600
      }
    },
    {
      "type": "trace",
      "file": "traces/tls-handshake.pcap",
      "filter": "tcp.port == 443 && tls.handshake.type == 1",
      "summary": "All connections use TLS 1.3 with perfect forward secrecy."
    }
  ]
}

These artifacts are linked in the SSP using evidence-id references:

- control-id: SI-2
  implementation: |
    All system-to-system communications are encrypted using TLS 1.3.
    Client authentication is required for internal APIs.
  evidence:
    - evidence-id: SI-2-cert-lb
    - evidence-id: SI-2-config-tls
    - evidence-id: SI-2-trace-pcap

The evidence-id is a URI or UUID stored in a central metadata database. When a reviewer clicks a control, they see the actual files and can validate the mapping.

Sharp Edge: Control Evidence Versioning

A subtle but common failure is evidence versioning mismatch. The SSP lists a tls-config.json file from January 2024, but the current system runs a modified version from March 2024. The control is marked as “implemented” but the evidence is outdated.

To prevent this, every evidence artifact is versioned using Git LFS or S3 object versioning. The system generates a evidence-manifest.json file that tracks versions:

{
  "evidence-id": "SI-2-config-tls",
  "file": "app/config/tls-config.json",
  "version": "v2.1.0",
  "created": "2024-03-10T12:00:00Z",
  "updated": "2024-03-15T09:30:00Z",
  "commit": "a1b2c3d4e5f6",
  "source": "https://github.com/company/app/commit/a1b2c3d4e5f6"
}

The validation pipeline checks that every evidence artifact’s version matches the control’s expected version. A mismatch triggers a control deviation in the CM system.

Automating Continuous Monitoring

FedRAMP requires continuous monitoring (CM), where security controls are assessed at least quarterly, with automated checks running daily.

The CM process is driven by a CM data pipeline that collects, processes, and reports assessment results.

The pipeline is defined in a cm-pipeline.yaml file:

pipeline:
  name: "FedRAMP Quarterly CM"
  frequency: "daily"
  stages:
    - name: "Collect Evidence"
      steps:
        - command: "run-openscap-scan"
          args:
            profile: "fedramp-moderate"
            output-dir: "/var/scan-results"
        - command: "export-audit-logs"
          args:
            start: "now-24h"
            format: "json"
            output: "/var/logs/audit-24h.json"
        - command: "capture-network-traffic"
          args:
            duration: "60s"
            filter: "tcp.port == 443"
            output: "/var/traces/tls-60s.pcap"
    - name: "Generate ARF"
      steps:
        - command: "oscap-xfce-merge"
          args:
            input: ["/var/scan-results/results.xml", "/var/logs/audit-24h.json"]
            output: "/var/cm-results/arf-merged.arf"
    - name: "Upload to FedRAMP CM System"
      steps:
        - command: "curl"
          args:
            method: "POST"
            url: "https://cm.fedramp.gov/api/assessments"
            headers:
              "Authorization": "Bearer $CM_API_TOKEN"
              "Content-Type": "application/xml"
            body: "/var/cm-results/arf-merged.arf"

The CM system expects a specific ARF structure. The arf-merged.arf file must include:

A common failure is missing or incorrect metadata. The CM system fails to ingest the ARF when the title is missing in the <metadata> section.

<arf:assessmentResult xmlns:arf="http://scap.nist.gov/scap/arf/1.1">
  <arf:metadata>
    <arf:title>FedRAMP CM Assessment 2024-03-15</arf:title>
    <arf:description>Daily assessment of Moderate-impact cloud system.</arf:description>
    <arf:version>1.0</arf:version>
    <arf:timestamp>2024-03-15T02:00:00Z</arf:timestamp>
  </arf:metadata>
  <arf:result id="SI-2" timestamp="2024-03-15T02:00:00Z" status="pass">
    <arf:check id="SI-2-tls-encryption" result="pass" />
    <arf:check id="SI-2-client-auth" result="fail" />
    <arf:metadata>
      <arf:title>SI-2: System and Communications Protection</arf:title>
      <arf:reference>https://fedramp.gov/controls/SI-2</arf:reference>
    </arf:metadata>
  </arf:result>
</arf:assessmentResult>

The CM system processes this ARF and updates the control status in real time. A control status dashboard shows:

Failure Mode: Stale Assessment Results

The pipeline runs daily, but the CM system only ingests results from the last 7 days. After two weeks of no uploads, the CM system shows “no assessment” for the current month. The root cause is a misconfigured cron job:

# /etc/cron.d/fedramp-cm
0 2 * * * root /opt/cm-pipeline.sh --output /var/cm-results/arf-merged.arf

The --output flag expects a full path, but the script writes to /var/cm-results/arf-merged.arf while the cron job runs from /root. The file is created in /root/var/cm-results/arf-merged.arf, which is not being uploaded.

The fix: ensure the script uses absolute paths and includes a cd /opt step.

Preparing for Re-authorization

Re-authorization occurs every three years and requires a full system update, new evidence, and a new SAR. The process is driven by a Re-Authorization Playbook.

The playbook is a sequence of steps with expected outcomes:

  1. Update SSP to reflect changes in the last three years
  2. Run full FedRAMP scan with --profile fedramp-high
  3. Generate SAR using generate-sar.py
  4. Collect new evidence for all controls
  5. Submit to FedRAMP CM System
  6. Verify control mapping using validate-control-mappings.sh

The validation script checks for:

# validate-control-mappings.sh
#!/bin/bash

set -euo pipefail

SSP_PATH="docs/ssps/2024-03-15-ssps.yaml"
EVIDENCE_DIR="evidence/"

while IFS= read -r -d '' control_id; do
  if ! [ -f "$EVIDENCE_DIR/$control_id.json" ]; then
    echo "ERROR: Missing evidence for control $control_id" >&2
    exit 1
  fi
done < <(yq '.controls[].control-id' $SSP_PATH | sort -u)

echo "All control evidence files found."

The re-authorization is considered complete when the CM system shows all controls as “passed” and the SAR is validated. The system is now ready for the FedRAMP Joint Authorization Board (JAB) review.

Final Check: Control Deviation Tracking

A final sharp edge is control deviation tracking. When a control fails, a deviation is opened. The deviation must include:

Deviations are stored in a deviations.json file:

{
  "control-id": "AC-2",
  "title": "User account provisioning is not fully synchronized",
  "description": "HR updates are not reflected in the cloud system within 1 hour.",
  "status": "open",
  "created": "2024-03-14T10:00:00Z",
  "due": "2024-04-14T10:00:00Z",
  "assignees": [
    "[email protected]",
    "[email protected]"
  ],
  "evidence": [
    "https://evidence.example.com/ac-2/2024-03-14-sync-issue.png",
    "https://api.example.com/v1/audits?control=AC-2&from=2024-03-14"
  ],
  "resolution": {
    "status": "in-progress",
    "progress": 0.6,
    "notes": "Working on real-time sync via Kafka."
  }
}

The CM system integrates deviations into the control view. A control marked as “failed” shows a link to the deviation, and the re-authorization review includes a checklist of all open deviations.

This pattern ensures that FedRAMP compliance is not a one-time task but a continuous, measurable, and auditable discipline.

This page was rewritten on 18 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.