Skip to the content.

Automating NIST SP 800-53 Compliance with OSCAL in DevSecOps

1. Model Your Compliance Once, in OSCAL

OSCAL breaks the world into layers/models. You’ll use these four the most:


2. GitOps Structure

  /oscal/
  profiles/        # tailored 800-53 profile (e.g., moderate-profile.json)
  components/      # component-definition files
  ssp/             # system-security-plan.json
  assessment-plan/ # plan.json (mapped to 800-53A procedures)
  assessment-results/   # results-[date].json
  poam/            # poam-[date].json
  sar/             # sar-[date].json

3. Create the Profile (Baseline)


4. Author Component Definitions

For each building block (AWS accounts, GuardDuty, Security Hub, WAF, Cloudflare, Auth0, ECS/EC2, RDS, S3, your Node/React app, logging pipeline, IR process), define:


5. Generate the SSP Automatically


6. Map 800-53A Procedures to Automated Checks

Define assessment methods:


7. CI/CD: Generate Assessment Results

Each pipeline run emits OSCAL Assessment Results:


Example: Component Definition

{
  "component-definition": {
    "uuid": "b1f0-...-abcd",
    "metadata": { "title": "AWS S3", "version": "2025-09-08" },
    "components": [{
      "type": "service",
      "title": "Amazon S3 (Encrypted + Lifecycle)",
      "implemented-requirements": [{
        "control-id": "SC-12",
        "statements": [{ "statement-id": "SC-12_smt.a", "description": "All buckets use KMS CMKs." }]
      },{
        "control-id": "AU-9",
        "statements": [{ "statement-id": "AU-9_smt.a", "description": "Logs backed up to immutable S3 bucket with MFA Delete." }]
      }]
    }]
  }
}

Example: Assessment Results

{
  "assessment-results": {
    "uuid": "9c2e-...-ef01",
    "results": [{
      "observations": [{
        "uuid": "obs-1",
        "method": "TEST",
        "subjects": [{ "type": "component", "href": "#s3" }],
        "relevant-evidence": [{ "description": "AWS CLI get-bucket-encryption output", "href": "s3://evidence/bucket.json" }],
        "remarks": "Bucket 'logs-archive' missing default encryption"
      }],
      "findings": [{
        "uuid": "f-1",
        "title": "S3 bucket missing default encryption",
        "related-observations": [{ "observation-uuid": "obs-1" }],
        "target": { "control-id": "SC-13" },
        "risk": { "title": "Unencrypted data at rest", "statement": "Compromise could expose PII" }
      }]
    }]
  }
}

8. Automate SAR & POA&M

Transform Assessment Results into:


9. Sample GitHub Actions Job

name: nist-800-53-oscal
on: [push, schedule]

jobs:
  build-ssp:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Compose SSP
        run: ./tools/oscal-compose --profile oscal/profiles/moderate.json \
                                   --components oscal/components/*.json \
                                   --out oscal/ssp/system-security-plan.json

  assess:
    runs-on: ubuntu-latest
    needs: build-ssp
    steps:
      - name: Cloud checks
        run: prowler -M json-asff > evidence/prowler.json
      - name: Generate AR
        run: ./tools/oscal-ar --ssp oscal/ssp/system-security-plan.json \
                              --map ./tools/mappings/800-53A.yaml \
                              --inputs evidence/ \
                              --out oscal/assessment-results/results-$(date +%F).json

10. Continuous Monitoring Loop