{"id":34075397,"url":"https://github.com/brasky/python-ssp","last_synced_at":"2025-12-14T09:40:08.188Z","repository":{"id":46261336,"uuid":"189128410","full_name":"brasky/python-ssp","owner":"brasky","description":"FedRAMP SSP API in Python","archived":false,"fork":false,"pushed_at":"2021-11-03T15:53:41.000Z","size":1888,"stargazers_count":11,"open_issues_count":1,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-09-04T16:57:19.128Z","etag":null,"topics":["automation","docx","fedramp","python","security-plan","ssp"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brasky.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-29T01:26:24.000Z","updated_at":"2023-11-28T22:45:34.000Z","dependencies_parsed_at":"2022-08-29T00:30:57.658Z","dependency_job_id":null,"html_url":"https://github.com/brasky/python-ssp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/brasky/python-ssp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brasky%2Fpython-ssp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brasky%2Fpython-ssp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brasky%2Fpython-ssp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brasky%2Fpython-ssp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brasky","download_url":"https://codeload.github.com/brasky/python-ssp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brasky%2Fpython-ssp/sbom","scorecard":{"id":251467,"data":{"date":"2025-08-11","repo":{"name":"github.com/brasky/python-ssp","commit":"ab92e20804307ed118884472cb65c8eadc195f87"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.8,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2016-21 / GHSA-34wj-p5jm-2p96","Warn: Project is vulnerable to: PYSEC-2017-48 / GHSA-chqf-hx79-gxc6"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T08:33:54.676Z","repository_id":46261336,"created_at":"2025-08-17T08:33:54.676Z","updated_at":"2025-08-17T08:33:54.676Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27725014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-14T02:00:11.348Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","docx","fedramp","python","security-plan","ssp"],"created_at":"2025-12-14T09:40:06.669Z","updated_at":"2025-12-14T09:40:08.174Z","avatar_url":"https://github.com/brasky.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/brasky/python-ssp.svg?branch=master)](https://travis-ci.org/brasky/python-ssp)\n\n# Table of Contents\n* [Overview](#Overview)\n* [Installation](#Installation)\n* [Usage](#Usage)\n    * [Opening an SSP](#Opening-an-SSP)\n    * [Viewing controls](#Viewing-controls)\n    * [Control attributes](#control-attributes)\n\n\n# Overview\n\n*python-ssp* is a Python library for interfacing with FedRAMP system security plan templates. It uses *[python-docx](https://github.com/python-openxml/python-docx)* as a base so controls can be accessed using the SSP api or using the underlying docx table object which allows both simplicity when you want it and feature richness depending on the use case.\n\n*python-ssp* is currently in an early development phase and was inspired to simplify import/export code in another project of mine, *[securityplanmanager](https://github.com/brasky/securityplanmanager)*.\n\n# Installation \n\nInstallation can be done either by cloning this repository:\n\n```\ngit clone https://github.com/brasky/python-ssp.git\ncd python-ssp\npip install -e .\n```\n\nor via pip directly:\n```\npip install python-ssp\n```\n\n## Dependencies\n- python-docx\n    - Python 3.3+\n    - lxml \u003e= 2.3.2\n\n# Usage\n\n## Opening an SSP\n\nFirst thing to do is open an SSP. Currently the only version supported is the newest template as of 7/4/2019 released 08/28/2018 on fedramp.gov/templates.\n\n```python\nfrom ssp import SSP\n\nsecurity_plan = SSP('path\\to\\securityplan.docx')\n```\n\nIf you get an error here, it could be because your document is not a supported template, or because of a Word object called \"Content Controls\" which are in the template around every table. To remove them, save the document as a .doc, it will tell you that it will remove content controls, then save it back to a .docx.\n\n## Viewing controls\n\nOnce your SSP is open, you probably want to look at information about your implementations. You can do this in a variety of ways:\n\n### Get a list of all the controls\n\nAn SSP object has a control_list attribute which has a list of all the controls that were identified on import. The `__iter__`  method is defined to return the control_list. You can loop through every control like so\n```python\nfor control in security_plan:\n...\n```\n\n### Get one specific control\n\nTo get a specific control you can use the `control` method which will return the corresponding control object\n```python\nsecurity_plan.control('AC-1')\n```\n\nControl objects are defined as a pair of tables (the CIS table and the implementation table), so they are the base control that is listed in the first cell of the CIS table. That's why it's passed `'AC-1'` as the control and not `'AC-1(a)'`.\n\n### Control parts\n\nAfter getting the control object you want, you can either get the part you want or get the list of parts the control has. Parts are equivalent to rows in the implementations table. \n\nThe part list is defined in the `parts` control attribute. For example, `security_plan.control('AC-2').parts` should return a list of parts 'a' through 'k'. The `__iter__` for control objects will iterate through parts, so you can do `for part in control` to loop through all the parts.\n\nThe `part()` method allows you to specify the part you want with `security_plan.control('AC-2').part('a')` and returns a docx cell object. To get the text you just add `.text`, so `security_plan.control('AC-2').part('a').text` will give you the implementation for AC-2(a).\n\nIf a control has no parts and just 1 implementation row, `.parts` will return `[None]` and `.parts(None)` will return the cell object for that implementation. For example:\n\n```python\nsecurity_plan.control('AC-2(3)').parts(None).text\n```\n\n This is an example of the alpha development phase in action and will be changed soon to something more readable.\n\n## Control Attributes\n\nOther control details are accessed through the following attributes:\n### Control Number\n`control_object.number` will return the control number as it's written in the first cell of the CIS table, so if you are looping through controls and you `print(control_object.number)` it will print \"AC-2\".\n\n### Responsible Role\n`security_plan.control('AC-2').responsible_role` will return everything to the right of the colon in the responsible role field as a string.\n\n### Control Origination\n`security_plan.control('AC-2').control_origination` will return a list of all the boxes checked in the control origination section.\n\n### Parameters\n`security_plan.control('AC-2').parameters` will return a list of all the parameter fields.\n\n### Implementation Status\n`security_plan.control('AC-2').implementation_status` will return a list of all the boxes checked in the implementation status section.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrasky%2Fpython-ssp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrasky%2Fpython-ssp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrasky%2Fpython-ssp/lists"}