Python class to validate, convert and manage OSCAL content.
Project description
OSCAL Python Library
This is a collection of python modules for OSCAL XML, JSON and YAML content. It provides classes for OSCAL content. The classes are able to perform validation, format conversion and some content manipulation.
It handles all published OSCAL versions, and can "learn" new versions as they are published by NIST.
Please submit feedback, bug reports and enhancement requests as GitHub issues. Bug fixes and backward-compatible code contributions are welcome. Please consider collaborating on any breaking enhancements.
Designed for Air Gapped Environments
The OSCAL_support class includes an OSCAL Support Module. This is a single SQLite3 database file that contains the NIST-published support files for all OSCAL formats, versions and models. The module enables support functionality in an air gapped environment.
When a new version of OSCAL is published, the support module can be updated on an Internet-connected computer and conveyed into an air gapped environment for use.
Inspection
Inspection of the OSCAL Support Module is possible using any SQLite database viewer. Note that the support files are ZIP compressed within the database; however, no encryption is used in order to facilitate inspection.
For more information see the Support Module documentation.
Setup
The Python OSCAL Class is intended to be used as a library for your OSCAL python projects.
Add the following to your requirements.txt file or pyproject.toml file:
-
Latest published version use:
oscal -
Most up-to-date, unpublished version use:
git+https://github.com/brian-ruf/oscal-class.git@develop#egg=oscal
Please see the Setup documentation for setup instructions and related details.
Usage: Quick Start
Installation
pip install oscal
To use the OSCAL classes in your code, import from the oscal library:
from oscal import Catalog
# Create a new catalog object
catalog = Catalog.new(
title="My Catalog",
version="DRAFT-1.0",
published="2026-03-02T00:00:00Z"
)
# Create a control group and controls
catalog.create_control_group("", "ac", "Access Control",
props=[{"name":"label", "value": "AC"},
{"name":"sort-id", "value": "001"}])
catalog.create_control("ac", "ac-1", "Access Control Policy and Procedures",
props=[{"name":"label", "value": "AC-1"},
{"name":"sort-id", "value": "001-001"}],
statements=["The organization develops, documents, and disseminates an access control policy that addresses purpose, scope, roles, responsibilities, management commitment, coordination among organizational entities, and compliance."])
catalog.create_control("ac", "ac-2", "Access Control Enforcement",
props=[{"name":"label", "value": "AC-2"},
{"name":"sort-id", "value": "001-002"}],
statements=["The organization enforces access control policies through technical and administrative mechanisms."])
# Save to multiple formats
catalog.dump("test_catalog.json", format="json", pretty_print=True)
catalog.dump("test_catalog.xml", format="xml", pretty_print=True)
catalog.dump("test_catalog.yaml", format="yaml", pretty_print=True)
Load OSCAL content from a file
Open OSCAL content directly from a local file:
from oscal import Catalog
# Load from file
catalog = Catalog.load("./catalog.xml")
# Save to other formats
catalog.dump("test_catalog.json", format="json", pretty_print=True)
catalog.dump("test_catalog.xml", format="xml", pretty_print=True)
catalog.dump("test_catalog.yaml", format="yaml", pretty_print=True)
Parse OSCAL content from a string
Use loads() with OSCAL content already in memory:
from oscal import OSCAL
oscal_content = """
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://csrc.nist.gov/ns/oscal/1.0" uuid="8e38fb28-f88e-4c3b-ac72-c39511a51f65">
<metadata>
<title>Control Catalog Template</title>
<published>2025-09-10T12:00:00-04:00</published>
<last-modified>2025-09-10T12:00:00-04:00</last-modified>
<version>DRAFT</version>
<oscal-version>1.1.3</oscal-version>
</metadata>
</catalog>
"""
catalog = OSCAL.loads(oscal_content)
Use of AI for Creating/Maintaining This Library
No portion of this library was "vibe coded".
Early versions of this library were written entirely without the use of AI tools.
Claude/Claude Code and GitHub Co-pilot have been used in a manner similar to pair-programming. This includes:
- options analysis when planning approaches
- improving alignment with "pythonic" best practices
- targeted code reviews
- resolving linter issues
- aid in debugging and testing
- drafting individual functions/methods that I refine and test
- drafting portions of documentation
- drafting/creating unit tests
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file oscal-2.0.0.tar.gz.
File metadata
- Download URL: oscal-2.0.0.tar.gz
- Upload date:
- Size: 8.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9e2874d0b44c5baa1758ce3f58b2796348adfd47b6f2e77bf3a6c25525d82bb
|
|
| MD5 |
3d5d304d8880c2cc93db78f8b80654f0
|
|
| BLAKE2b-256 |
29a6e3183d07e73d15d0a52defdd0e5ee5c696197690305cf2e35247b8a93e7a
|
Provenance
The following attestation bundles were made for oscal-2.0.0.tar.gz:
Publisher:
publish.yml on brian-ruf/oscal-class
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oscal-2.0.0.tar.gz -
Subject digest:
a9e2874d0b44c5baa1758ce3f58b2796348adfd47b6f2e77bf3a6c25525d82bb - Sigstore transparency entry: 1392601467
- Sigstore integration time:
-
Permalink:
brian-ruf/oscal-class@f84dac391c7280ac23a5757030364b30da36b675 -
Branch / Tag:
refs/tags/v2.0.0 - Owner: https://github.com/brian-ruf
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f84dac391c7280ac23a5757030364b30da36b675 -
Trigger Event:
release
-
Statement type:
File details
Details for the file oscal-2.0.0-py3-none-any.whl.
File metadata
- Download URL: oscal-2.0.0-py3-none-any.whl
- Upload date:
- Size: 8.6 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21c4f2763d14b2192343ecf49c58eb84cddeaf0cf4ac7e52f4081a0d4b15ea2a
|
|
| MD5 |
4c944e12e97008aeeda8d2c50f6f0387
|
|
| BLAKE2b-256 |
0f7251a407c5089d5a7b631e011f30e61b43fb8a5f403d41ea35cbff0676e155
|
Provenance
The following attestation bundles were made for oscal-2.0.0-py3-none-any.whl:
Publisher:
publish.yml on brian-ruf/oscal-class
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oscal-2.0.0-py3-none-any.whl -
Subject digest:
21c4f2763d14b2192343ecf49c58eb84cddeaf0cf4ac7e52f4081a0d4b15ea2a - Sigstore transparency entry: 1392601470
- Sigstore integration time:
-
Permalink:
brian-ruf/oscal-class@f84dac391c7280ac23a5757030364b30da36b675 -
Branch / Tag:
refs/tags/v2.0.0 - Owner: https://github.com/brian-ruf
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f84dac391c7280ac23a5757030364b30da36b675 -
Trigger Event:
release
-
Statement type: