GRC tooling for policy documents. Ingests Markdown natively; uses Firecrawl anydoc for Word, PowerPoint, Excel, OpenDocument, RTF, EPUB, and CSV; and uses Firecrawl pdf-inspector for PDF classification and extraction (anydoc is the PDF fallback when pdf-inspector is not installed).
- Extract control-related statements from policy and procedure documents.
- Keep content-addressed version history for corporate docs.
- Map statements to frameworks via the SCF API (Secure Controls Framework), plus OpenCRE, OSA, NIST OSCAL, FedRAMP CR26 KSI, and seed maps.
- Alert when wording changes may affect frameworks, assessments, or certifications.
- Keep documentation and policy-as-code (Terraform) in lock-step.
These commands install this repository into your Python environment in
editable mode (-e): code changes apply without reinstall.
| Extra | What it adds |
|---|---|
| (none) | Core library + grc-pdf CLI |
dev |
pytest (for tests) |
pdf |
pdf-inspector for PDF class / OCR hints |
anydoc |
anydoc for office formats (+ PDF fallback) |
docs |
Both pdf and anydoc |
ui |
Local dark GUI (grc-pdf ui) via FastAPI + uvicorn |
From the repository root (grc-pdf-mapper/):
cd grc-pdf-mapper
python3 -m pip install -e ".[dev]"Optional document ingest (Markdown works without these):
python3 -m pip install -e ".[docs,ui,dev]"Office-only (no pdf-inspector):
python3 -m pip install -e ".[anydoc,dev]"Install UI deps, then open a dark local workbench in the browser:
python3 -m pip install -e ".[docs,ui]"
grc-pdf uiOpen http://127.0.0.1:8765/ (the command opens a tab by default). Drop a policy file or choose one. The page shows obligations, framework hits, CSV exports, Markdown, and downloadable JSON. The server binds to localhost only.
grc-pdf ui --port 8765 --no-browserIf grc-pdf is not found, add your user script path (common on Linux):
export PATH="$HOME/.local/bin:$PATH"Or run as a module:
python3 -m grc_pdf_mapper --helpConfirm the CLI:
grc-pdf --helpgrc-pdf analyze tests/fixtures/access_control_policy_v1.md \
--doc-id pol-ac-001 --version v2.1 --offline --json report.json \
--csv-frameworks frameworks.csv --csv-controls controls.csv
grc-pdf analyze tests/fixtures/access_control_policy.docx \
--doc-id pol-ac-docx --version v1 --offline --no-commit
grc-pdf analyze tests/fixtures/access_control_policy_v2.md \
--doc-id pol-ac-001 --version v2.2 --offline
grc-pdf history pol-ac-001
grc-pdf ask report.json "Do you require MFA for privileged production access?"
grc-pdf evidence report.json AC-2Live gallery (GitHub Pages):
https://kfcain.github.io/grc-pdf-mapper/
Gallery source: examples/viewer/. Published from docs/ on the main branch.
Regenerate demo artifacts:
bash examples/sync_pages_gallery.sh| Lab | Path |
|---|---|
| Document change control + GitHub Actions | lab/README.md |
| Policy-as-code lock-step (docs ↔ Terraform) | lab/POLICY-AS-CODE.md |
| Production cross-repository monitoring | docs/PRODUCTION-CROSS-REPO.md |
| FedRAMP CR26 KSI (Classes A–D) | lab/FEDRAMP-CR26-KSI.md |
Local simulations:
bash lab/simulate_risky_pr.sh
bash lab/simulate_pac_lockstep.shMarkdown / PDF / Word / Excel / RTF / …
→ Markdown or txt (native)
→ pdf-inspector (PDF; class + OCR hints)
→ anydoc (office formats; PDF fallback)
→ control statement miner
→ crosswalk (seed / OpenCRE / OSA / OSCAL / FedRAMP KSI)
→ lineage store
→ alerts · blast radius · questionnaire · evidence · OSCAL · sync
| Engine | Formats |
|---|---|
| Native | .md, .markdown, .txt |
| pdf-inspector | .pdf (preferred when installed) |
| anydoc | .doc .docx .docm · .ppt .pptx … · .xls .xlsx … · .odt .ods .odp · .rtf · .epub · .csv · .pdf (fallback) |
| Source | Role |
|---|---|
| SCF API | Primary backbone — 1,468 SCF controls × 249 framework crosswalks (grcengclub.github.io/scf-api, by ethanolivertroy / GRCEngClub) |
| OpenCRE | Standard sections → Common Requirements |
| Open Security Architecture (OSA) | Framework crosswalks |
| NIST OSCAL | SP 800-53 control titles |
| FedRAMP CR26 KSI | Key Security Indicators + certification doc FRRs by class |
| Seed map | Offline topic → control hints |
Use --offline for air-gapped runs (bundled SCF seed + local catalogs).
Map one control through SCF:
grc-pdf scf-map AC-2
grc-pdf scf-map IAC-01 --offlinegrc-pdf impact <doc-id> <older-snap> <newer-snap>
grc-pdf watch ./policies/access-control.md --doc-id pol-ac-001
grc-pdf ui
grc-pdf sync-check
grc-pdf pac-impact iac-changed --base-tf base.tf --head-tf head.tf
grc-pdf pac-impact change-set \
--base-policy base-policy.md --head-policy head-policy.md \
--base-tf-root /tmp/base-repository --head-tf-root . \
--assessments lab/assessments.json --json pac-alert.json
grc-pdf classifier-validate tests/fixtures/classifier_corpus.json \
--minimum-score 0.95 --json classifier-validation.json
grc-pdf production-monitor examples/production-monitor.json \
--state /protected/grc-state/production.json \
--fail-on medium --json production-monitor-report.json
grc-pdf fedramp-ksi --class c --control IA-2
grc-pdf fedramp-docs --class c --must-only
grc-pdf scf-map AC-2change-set scans every .tf file below both Terraform roots. It evaluates
the policy and Terraform changes together, keeps resources in separate module
directories distinct, and enriches affected policy-to-code links with SCF and
SCF framework crosswalks. Add --online-scf to use the live SCF API. The
default uses the bundled offline SCF data.
The policy classifier joins wrapped paragraphs and shared-modal lists, keeps Markdown table rows and heading scope, and separates obligations from prohibitions, recommendations, permissions, responsibilities, and citations, and records confidence plus evidence reasons. The Terraform classifier assigns security domains, candidate controls, enforcement roles, configuration posture, confidence, and reasons to each security-relevant resource. Changed Terraform classifications are enriched through SCF in the same change-set report.
production-monitor evaluates one or more documentation repositories and any
number of production IaC repositories. It pins each input to a full Git commit ID, uses
repository-qualified Terraform identities, checks classifier output against
exact human-reviewed domains and policy semantics, rejects unpinned or linked source
files, records file and catalog digests, and sends deduplicated
webhook events for a mismatch or recovery. See the
production guide and the
GitHub Actions example.
src/grc_pdf_mapper/ # library + CLI (incl. SCF API client)
lab/ # sample policies, IaC, FedRAMP catalog, playbooks
examples/viewer/ # static example gallery
docs/ # GitHub Pages gallery + architecture notes
scripts/ # CI helpers
tests/ # pytest suite
.github/workflows/ # document + policy-as-code gates
pytest -qOffice ingest tests need firecrawl-anydoc:
python3 -m pip install -e ".[anydoc,dev]"
pytest -q tests/test_ingest_anydoc.pyOffice conversion uses Firecrawl anydoc.
PDF classification and extraction use Firecrawl pdf-inspector when installed.
Control mappings use the Secure Controls Framework via the SCF API (CC BY-ND 4.0).
MIT