diff --git a/.gitignore b/.gitignore index c1559fa3..66d61b2b 100644 --- a/.gitignore +++ b/.gitignore @@ -158,4 +158,7 @@ cython_debug/ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ \ No newline at end of file +#.idea/ + +# Local VSCode +.vscode/ \ No newline at end of file diff --git a/README.md b/README.md index fccedb74..f0ec9686 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # trestle-bot -trestle-bot assists users in leveraging [Compliance-Trestle](https://github.com/IBM/compliance-trestle) in automated workflows of for [OSCAL](https://github.com/usnistgov/OSCAL) formatted compliance content management. +trestle-bot assists users in leveraging [Compliance-Trestle](https://github.com/IBM/compliance-trestle) in automated workflows or [OSCAL](https://github.com/usnistgov/OSCAL) formatted compliance content management. In addition to trestle-bot, this repo contains the trestle-bot GitHub Action that can optionally be used to host the tresle-bot service within GitHub Actions. diff --git a/action.yml b/action.yml index 643b9f54..82b55c52 100644 --- a/action.yml +++ b/action.yml @@ -3,6 +3,16 @@ author: "Red Hat Product Security" description: "A workflow automation manager for OSCAL formatted compliance content" inputs: + markdown_path: + description: Path relative to the repository path where the Trestle markdown files are located. See project README.md for more information. + required: true + assemble_model: + description: OSCAL Model type to assemble. Values can be catalog, profile, compdef, or ssp. + required: true + ssp_index_path: + description: Path relative to the repository path where the ssp index is located. See project README.md for information about the ssp index. + required: false + default: "ssp-index.txt" commit_message: description: Commit message required: false diff --git a/poetry.lock b/poetry.lock index 2c84d0f9..40872633 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,92 @@ # This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +[[package]] +name = "anyio" +version = "3.7.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.7" +files = [ + {file = "anyio-3.7.0-py3-none-any.whl", hash = "sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0"}, + {file = "anyio-3.7.0.tar.gz", hash = "sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce"}, +] + +[package.dependencies] +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" + +[package.extras] +doc = ["Sphinx (>=6.1.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme", "sphinxcontrib-jquery"] +test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (<0.22)"] + +[[package]] +name = "argcomplete" +version = "3.1.1" +description = "Bash tab completion for argparse" +optional = false +python-versions = ">=3.6" +files = [ + {file = "argcomplete-3.1.1-py3-none-any.whl", hash = "sha256:35fa893a88deea85ea7b20d241100e64516d6af6d7b0ae2bed1d263d26f70948"}, + {file = "argcomplete-3.1.1.tar.gz", hash = "sha256:6c4c563f14f01440aaffa3eae13441c5db2357b5eec639abe7c0b15334627dff"}, +] + +[package.extras] +test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] + +[[package]] +name = "attrs" +version = "23.1.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] + +[[package]] +name = "bcrypt" +version = "4.0.1" +description = "Modern password hashing for your software and your servers" +optional = false +python-versions = ">=3.6" +files = [ + {file = "bcrypt-4.0.1-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:b1023030aec778185a6c16cf70f359cbb6e0c289fd564a7cfa29e727a1c38f8f"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:08d2947c490093a11416df18043c27abe3921558d2c03e2076ccb28a116cb6d0"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0eaa47d4661c326bfc9d08d16debbc4edf78778e6aaba29c1bc7ce67214d4410"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae88eca3024bb34bb3430f964beab71226e761f51b912de5133470b649d82344"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:a522427293d77e1c29e303fc282e2d71864579527a04ddcfda6d4f8396c6c36a"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:fbdaec13c5105f0c4e5c52614d04f0bca5f5af007910daa8b6b12095edaa67b3"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ca3204d00d3cb2dfed07f2d74a25f12fc12f73e606fcaa6975d1f7ae69cacbb2"}, + {file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:089098effa1bc35dc055366740a067a2fc76987e8ec75349eb9484061c54f535"}, + {file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:e9a51bbfe7e9802b5f3508687758b564069ba937748ad7b9e890086290d2f79e"}, + {file = "bcrypt-4.0.1-cp36-abi3-win32.whl", hash = "sha256:2caffdae059e06ac23fce178d31b4a702f2a3264c20bfb5ff541b338194d8fab"}, + {file = "bcrypt-4.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:8a68f4341daf7522fe8d73874de8906f3a339048ba406be6ddc1b3ccb16fc0d9"}, + {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf4fa8b2ca74381bb5442c089350f09a3f17797829d958fad058d6e44d9eb83c"}, + {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:67a97e1c405b24f19d08890e7ae0c4f7ce1e56a712a016746c8b2d7732d65d4b"}, + {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b3b85202d95dd568efcb35b53936c5e3b3600c7cdcc6115ba461df3a8e89f38d"}, + {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbb03eec97496166b704ed663a53680ab57c5084b2fc98ef23291987b525cb7d"}, + {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:5ad4d32a28b80c5fa6671ccfb43676e8c1cc232887759d1cd7b6f56ea4355215"}, + {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b57adba8a1444faf784394de3436233728a1ecaeb6e07e8c22c8848f179b893c"}, + {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:705b2cea8a9ed3d55b4491887ceadb0106acf7c6387699fca771af56b1cdeeda"}, + {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:2b3ac11cf45161628f1f3733263e63194f22664bf4d0c0f3ab34099c02134665"}, + {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3100851841186c25f127731b9fa11909ab7b1df6fc4b9f8353f4f1fd952fbf71"}, + {file = "bcrypt-4.0.1.tar.gz", hash = "sha256:27d375903ac8261cfe4047f6709d16f7d18d39b1ec92aaf72af989552a650ebd"}, +] + +[package.extras] +tests = ["pytest (>=3.2.1,!=3.3.0)"] +typecheck = ["mypy"] + [[package]] name = "black" version = "23.3.0" @@ -49,6 +136,188 @@ d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "certifi" +version = "2023.5.7" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, + {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, +] + +[[package]] +name = "cffi" +version = "1.15.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = "*" +files = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "chardet" +version = "5.1.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.1.0-py3-none-any.whl", hash = "sha256:362777fb014af596ad31334fde1e8c327dfdb076e1960d1694662d46a6917ab9"}, + {file = "chardet-5.1.0.tar.gz", hash = "sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.1.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, + {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, +] + [[package]] name = "click" version = "8.1.3" @@ -63,6 +332,68 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} +[[package]] +name = "cmarkgfm" +version = "0.6.0" +description = "Minimal bindings to GitHub's fork of cmark" +optional = false +python-versions = "*" +files = [ + {file = "cmarkgfm-0.6.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:02f14c7e77fcddf044df14cc227d7703027ee720bac719616ac505af29812b73"}, + {file = "cmarkgfm-0.6.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:786e8a06f7eec6eb3f3789353a586c8b065570d2db9811fdcdaced736a36ce53"}, + {file = "cmarkgfm-0.6.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:b04da61652984c89868b31aface2d75e3d26081273d3764e18b5661eea98916e"}, + {file = "cmarkgfm-0.6.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:6a48a67ff8425b4dee33196f6cd9bdba7b902c0b7e369150f6704989f9c40476"}, + {file = "cmarkgfm-0.6.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3157b37d1a897ee57ae57be8eafac3659e31fdce33fbbc85f76df34ee2804d5a"}, + {file = "cmarkgfm-0.6.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:82cfc1bc7099fa819993c41d3c6778bff29e5547dbf1de1dbb113ef4d2bc0df9"}, + {file = "cmarkgfm-0.6.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:89cc51c26a10ebdaada4ed2630f6f375cf059d3aca5d77aff493a2010f6ed60a"}, + {file = "cmarkgfm-0.6.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:94ba213739648006232aa917f8c4c42c520812601d85502fa7a5dad0f0d1590e"}, + {file = "cmarkgfm-0.6.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6bb05e1b4adc8027c41ddbd11761482c652f1aa2ae4419469e3883ec8b0bdf67"}, + {file = "cmarkgfm-0.6.0-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:c61f3f2cd2b9c44cb2579e165a18f824a6c99682aff10ac2779a7a74a3167e89"}, + {file = "cmarkgfm-0.6.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:427ca60eb2f56c6293ac0e91b728acf608297c9030dccd3c928e938b3bf3ee77"}, + {file = "cmarkgfm-0.6.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:706daefce3f9bd1cd955b6bb06beac31c050b65f4bec8025dade3b0f05dbeed2"}, + {file = "cmarkgfm-0.6.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:d4422e0dd3a11eeebbe86c6c08ac1c28783efed4b7b948a9878724e677eda107"}, + {file = "cmarkgfm-0.6.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:e550ca0826eab1ab87d9eed58da89cc113f13f369fdd61c799705007422dbfce"}, + {file = "cmarkgfm-0.6.0-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:7641061c0bc4caf754f119c326131ad41c25beb1e95e2479e8aab60dbd8f9f79"}, + {file = "cmarkgfm-0.6.0-cp35-cp35m-win32.whl", hash = "sha256:7a974b3b90805f656054d6873cd876ee5c7949e7860d131b7ec0b29a3de3a3f3"}, + {file = "cmarkgfm-0.6.0-cp35-cp35m-win_amd64.whl", hash = "sha256:6377e46d854cc32e03933a44a0b6e6750cf89b4314e1c84958a7a547c3952c23"}, + {file = "cmarkgfm-0.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3a31b239dfe4945fcb6a53fcb7dac64cb857ecfb1f710d891ff96955c64509f6"}, + {file = "cmarkgfm-0.6.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:ce717bd3e26a95b749fbbf68da42cc5cb9200779a4943bbdd38fa73711366081"}, + {file = "cmarkgfm-0.6.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8eebdc5ca2cd565998195d1e6189d5979a00a5db9c579d05953478cb085ef435"}, + {file = "cmarkgfm-0.6.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:ccbfb5e427ca815d80962e6705834ebadeb55058ac745e0339fb570bb78a6114"}, + {file = "cmarkgfm-0.6.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:737e4525c63ae3bca731e5c57056c02078e31e579ec655b72bd28eae525d6b53"}, + {file = "cmarkgfm-0.6.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:e7b5b6cd8befa8c1cf2a55f750a4dcf84de05c80a7110d933ea6724fbc6d2cf8"}, + {file = "cmarkgfm-0.6.0-cp36-cp36m-win32.whl", hash = "sha256:f0da78ef960f57aec8a6854821a99fa7a520dad77631b19becb68b2ebf8dbc2d"}, + {file = "cmarkgfm-0.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:3a5138d76e93378a72fb7a704cbf09764ebb43cfcf121e6d7ffdc40fb7917d4a"}, + {file = "cmarkgfm-0.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:605bd69fa4b247be9bb4e7d75bda4df37428a153e3a67aca50d7cd9dc1ee8225"}, + {file = "cmarkgfm-0.6.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:57e4f57aa9264a3244a28665d3c5ec81b1ace454b01a1c09ff0d67a2cd12ca5a"}, + {file = "cmarkgfm-0.6.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:989432956e34591387f0aaab98caabd699f2f5d4c708d1a0d882334a8b760cc5"}, + {file = "cmarkgfm-0.6.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:713bd4e64651e7bbd897bbaee6057c16b72c6ac3cf59b2b38892d635d52755eb"}, + {file = "cmarkgfm-0.6.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:c58c904c22b946d436637e8e1987db5886af8041c57e0028c419f98075344f1f"}, + {file = "cmarkgfm-0.6.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:7262bb2b875d1c47dfa0e074fe349eb1ba1901e323fcf9e3fc4dbf97f0b92d97"}, + {file = "cmarkgfm-0.6.0-cp37-cp37m-win32.whl", hash = "sha256:8be0c52d0caf1852a5374c7c9a279801c1a8dd9e2040939e75262d02b003835b"}, + {file = "cmarkgfm-0.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:8f901c002172a3be8bb91a422da23dfae0301afe062addf41c976385f96bc1ef"}, + {file = "cmarkgfm-0.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b58277117a439fd27aee2bcc8869be334fb7e8781e27066ec31ec0a596a6a01"}, + {file = "cmarkgfm-0.6.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:13c34b6dc5b77100201c543cd205366ef7ecc612efce4247e2b7a0bb258b271e"}, + {file = "cmarkgfm-0.6.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:e66f15d4c645c87819f7170990a00e0fa9e0e8255097f8bd5eb3037d78264efb"}, + {file = "cmarkgfm-0.6.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:371c4a2d88508800f6cc872082970afdb414f2d3b86ac7769419f27da0d43acc"}, + {file = "cmarkgfm-0.6.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4121f6047c4d4a28ded3cf02c087869549e9f0c3712e5a2af180972f9d1348a5"}, + {file = "cmarkgfm-0.6.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:a386b01a266a42e8e9052c74ad42dc1ff50b209d8958a3656e0435fa018a0223"}, + {file = "cmarkgfm-0.6.0-cp38-cp38-win32.whl", hash = "sha256:ae6796d4e8ea746dc8e29173f95ffb9b12f940ff5b9186d10203445526cf8d4d"}, + {file = "cmarkgfm-0.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:872f3c9d99aedf55ad6950a4158873a107f6338040bc381b21849ccf165e9d90"}, + {file = "cmarkgfm-0.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa28b1a335adb5bad04b4a50382cbcfcc6c8d68413ba35e2cd3f657a1dc76347"}, + {file = "cmarkgfm-0.6.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:791c7f8aed353d540aed52c6724df408eb73208d7c9dd98aae6506d5783cb95f"}, + {file = "cmarkgfm-0.6.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b594063a3421561e0559cc5a68419cdcb020512fc40c3eb37e4629bae2a954b6"}, + {file = "cmarkgfm-0.6.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:0c5d762351f14479b07bfda6773905caa0fa7f132f6478c35e467d0be21e9f2e"}, + {file = "cmarkgfm-0.6.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c17e19db003f86662d08ce382912767f7221637703a64cfdb85b8c1447cc4b36"}, + {file = "cmarkgfm-0.6.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f56aa4940aa4ee98fd6f3e0a648b8ae1e6a27f5007d64d406aeadc51451dc13b"}, + {file = "cmarkgfm-0.6.0-cp39-cp39-win32.whl", hash = "sha256:51134e3775ac7c47ca2430a53b02c6ff03463143af8dfaeb1575c03e039ee485"}, + {file = "cmarkgfm-0.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:3c7053c8650bf1f79c607dc88ff56652d07f52aac4b60aa1bf07529c9b4473a7"}, + {file = "cmarkgfm-0.6.0.tar.gz", hash = "sha256:ec2bf8d5799c4b5bbfbae30a4a1dfcb06512f2e17e9ee60ba7e1d390318582fc"}, +] + +[package.dependencies] +cffi = ">=1.0.0" + [[package]] name = "colorama" version = "0.4.6" @@ -74,6 +405,38 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "compliance-trestle" +version = "2.1.1" +description = "Tools to manage & autogenerate python objects representing the OSCAL layers/models" +optional = false +python-versions = "*" +files = [ + {file = "compliance-trestle-2.1.1.tar.gz", hash = "sha256:78c657dd157bba375ab7cbcb9654e8efbf10d51201518061e67a1c2f32329275"}, + {file = "compliance_trestle-2.1.1-py2.py3-none-any.whl", hash = "sha256:dd3dc11df625cc9374cf0797a77751b0ff2ed4b9b5e98a2336836915d54438d7"}, +] + +[package.dependencies] +attrs = "*" +cmarkgfm = "==0.6.*" +cryptography = "*" +datamodel-code-generator = {version = ">=0.11.14", extras = ["http"]} +defusedxml = "*" +furl = "*" +ilcli = "*" +Jinja2 = ">=3.0.1" +openpyxl = ">=3.0,<4.0" +orjson = "*" +paramiko = "*" +pydantic = {version = ">=1.8.2", extras = ["email"]} +python-dotenv = ">=0.10.4" +python-frontmatter = "*" +pywin32 = {version = ">=1.0", markers = "platform_system == \"Windows\""} +"ruamel.yaml" = "*" + +[package.extras] +dev = ["gitpython", "livereload", "markdown-include", "mkdocs", "mkdocs-material", "mkdocstrings[python-legacy] (>=0.19.0)", "mypy", "pep8-naming", "pre-commit (>=2.4.0)", "pylint", "pymdown-extensions", "pytest (>=5.4.3)", "pytest-cov (>=2.10.0)", "pytest-random-order", "pytest-xdist", "python-dateutil", "python-semantic-release", "setuptools", "types-PyYAML", "types-paramiko", "types-requests", "types-setuptools", "wheel", "yapf"] + [[package]] name = "coverage" version = "7.2.7" @@ -149,6 +512,137 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "cryptography" +version = "41.0.1" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-41.0.1-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:f73bff05db2a3e5974a6fd248af2566134d8981fd7ab012e5dd4ddb1d9a70699"}, + {file = "cryptography-41.0.1-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:1a5472d40c8f8e91ff7a3d8ac6dfa363d8e3138b961529c996f3e2df0c7a411a"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fa01527046ca5facdf973eef2535a27fec4cb651e4daec4d043ef63f6ecd4ca"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b46e37db3cc267b4dea1f56da7346c9727e1209aa98487179ee8ebed09d21e43"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d198820aba55660b4d74f7b5fd1f17db3aa5eb3e6893b0a41b75e84e4f9e0e4b"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:948224d76c4b6457349d47c0c98657557f429b4e93057cf5a2f71d603e2fc3a3"}, + {file = "cryptography-41.0.1-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:059e348f9a3c1950937e1b5d7ba1f8e968508ab181e75fc32b879452f08356db"}, + {file = "cryptography-41.0.1-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:b4ceb5324b998ce2003bc17d519080b4ec8d5b7b70794cbd2836101406a9be31"}, + {file = "cryptography-41.0.1-cp37-abi3-win32.whl", hash = "sha256:8f4ab7021127a9b4323537300a2acfb450124b2def3756f64dc3a3d2160ee4b5"}, + {file = "cryptography-41.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:1fee5aacc7367487b4e22484d3c7e547992ed726d14864ee33c0176ae43b0d7c"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9a6c7a3c87d595608a39980ebaa04d5a37f94024c9f24eb7d10262b92f739ddb"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5d092fdfedaec4cbbffbf98cddc915ba145313a6fdaab83c6e67f4e6c218e6f3"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a8e6c2de6fbbcc5e14fd27fb24414507cb3333198ea9ab1258d916f00bc3039"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb33ccf15e89f7ed89b235cff9d49e2e62c6c981a6061c9c8bb47ed7951190bc"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f0ff6e18d13a3de56f609dd1fd11470918f770c6bd5d00d632076c727d35485"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7bfc55a5eae8b86a287747053140ba221afc65eb06207bedf6e019b8934b477c"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:eb8163f5e549a22888c18b0d53d6bb62a20510060a22fd5a995ec8a05268df8a"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8dde71c4169ec5ccc1087bb7521d54251c016f126f922ab2dfe6649170a3b8c5"}, + {file = "cryptography-41.0.1.tar.gz", hash = "sha256:d34579085401d3f49762d2f7d6634d6b6c2ae1242202e860f4d26b046e3a1006"}, +] + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] +nox = ["nox"] +pep8test = ["black", "check-sdist", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "datamodel-code-generator" +version = "0.20.0" +description = "Datamodel Code Generator" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "datamodel_code_generator-0.20.0-py3-none-any.whl", hash = "sha256:fdb8dc18fd3a5d2c92e5e3ac473c5a48f3540066941e56fd947d2975cfebd281"}, + {file = "datamodel_code_generator-0.20.0.tar.gz", hash = "sha256:84dc7d6ae64ca67834b414c107adf3510f46a474ac21467a683aca0a4a8f0806"}, +] + +[package.dependencies] +argcomplete = ">=1.10,<4.0" +black = ">=19.10b0" +genson = ">=1.2.1,<2.0" +httpx = {version = "*", optional = true, markers = "extra == \"http\""} +inflect = ">=4.1.0,<6.0" +isort = ">=4.3.21,<6.0" +jinja2 = ">=2.10.1,<4.0" +openapi-spec-validator = ">=0.2.8,<=0.5.2" +packaging = "*" +prance = ">=0.18.2,<1.0" +pydantic = [ + {version = ">=1.10.0,<2.0.0", extras = ["email"], markers = "python_version >= \"3.11\" and python_version < \"4.0\""}, + {version = ">=1.5.1,<2.0.0", extras = ["email"], markers = "python_version < \"3.10\""}, + {version = ">=1.9.0,<2.0.0", extras = ["email"], markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, +] +PySnooper = ">=0.4.1,<2.0.0" +toml = ">=0.10.0,<1.0.0" + +[package.extras] +http = ["httpx"] + +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + +[[package]] +name = "dnspython" +version = "2.3.0" +description = "DNS toolkit" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "dnspython-2.3.0-py3-none-any.whl", hash = "sha256:89141536394f909066cabd112e3e1a37e4e654db00a25308b0f130bc3152eb46"}, + {file = "dnspython-2.3.0.tar.gz", hash = "sha256:224e32b03eb46be70e12ef6d64e0be123a64e621ab4c0822ff6d450d52a540b9"}, +] + +[package.extras] +curio = ["curio (>=1.2,<2.0)", "sniffio (>=1.1,<2.0)"] +dnssec = ["cryptography (>=2.6,<40.0)"] +doh = ["h2 (>=4.1.0)", "httpx (>=0.21.1)", "requests (>=2.23.0,<3.0.0)", "requests-toolbelt (>=0.9.1,<0.11.0)"] +doq = ["aioquic (>=0.9.20)"] +idna = ["idna (>=2.1,<4.0)"] +trio = ["trio (>=0.14,<0.23)"] +wmi = ["wmi (>=1.5.1,<2.0.0)"] + +[[package]] +name = "email-validator" +version = "2.0.0.post2" +description = "A robust email address syntax and deliverability validation library." +optional = false +python-versions = ">=3.7" +files = [ + {file = "email_validator-2.0.0.post2-py3-none-any.whl", hash = "sha256:2466ba57cda361fb7309fd3d5a225723c788ca4bbad32a0ebd5373b99730285c"}, + {file = "email_validator-2.0.0.post2.tar.gz", hash = "sha256:1ff6e86044200c56ae23595695c54e9614f4a9551e0e393614f764860b3d7900"}, +] + +[package.dependencies] +dnspython = ">=2.0.0" +idna = ">=2.0.0" + +[[package]] +name = "et-xmlfile" +version = "1.1.0" +description = "An implementation of lxml.xmlfile for the standard library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, + {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, +] + [[package]] name = "exceptiongroup" version = "1.1.1" @@ -179,6 +673,31 @@ mccabe = ">=0.7.0,<0.8.0" pycodestyle = ">=2.10.0,<2.11.0" pyflakes = ">=3.0.0,<3.1.0" +[[package]] +name = "furl" +version = "2.1.3" +description = "URL manipulation made simple." +optional = false +python-versions = "*" +files = [ + {file = "furl-2.1.3-py2.py3-none-any.whl", hash = "sha256:9ab425062c4217f9802508e45feb4a83e54324273ac4b202f1850363309666c0"}, + {file = "furl-2.1.3.tar.gz", hash = "sha256:5a6188fe2666c484a12159c18be97a1977a71d632ef5bb867ef15f54af39cc4e"}, +] + +[package.dependencies] +orderedmultidict = ">=1.0.1" +six = ">=1.8.0" + +[[package]] +name = "genson" +version = "1.2.2" +description = "GenSON is a powerful, user-friendly JSON Schema generator." +optional = false +python-versions = "*" +files = [ + {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, +] + [[package]] name = "gitdb" version = "4.0.10" @@ -207,6 +726,119 @@ files = [ [package.dependencies] gitdb = ">=4.0.1,<5" +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "0.17.2" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.7" +files = [ + {file = "httpcore-0.17.2-py3-none-any.whl", hash = "sha256:5581b9c12379c4288fe70f43c710d16060c10080617001e6b22a3b6dbcbefd36"}, + {file = "httpcore-0.17.2.tar.gz", hash = "sha256:125f8375ab60036db632f34f4b627a9ad085048eef7cb7d2616fea0f739f98af"}, +] + +[package.dependencies] +anyio = ">=3.0,<5.0" +certifi = "*" +h11 = ">=0.13,<0.15" +sniffio = "==1.*" + +[package.extras] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + +[[package]] +name = "httpx" +version = "0.24.1" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.7" +files = [ + {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, + {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, +] + +[package.dependencies] +certifi = "*" +httpcore = ">=0.15.0,<0.18.0" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + +[[package]] +name = "idna" +version = "3.4" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] + +[[package]] +name = "ilcli" +version = "0.3.2" +description = "i like command-line interfaces" +optional = false +python-versions = "*" +files = [ + {file = "ilcli-0.3.2-py2.py3-none-any.whl", hash = "sha256:dfb7d2da49c63ef92c5a589eb5f765d073d7ea83275c3dd2aea8ae5cbe4c5be2"}, + {file = "ilcli-0.3.2.tar.gz", hash = "sha256:8a56b053836f8b0e1bbbdda884288d18dc966bd8e90fdf9b340914dba625cd7f"}, +] + +[package.extras] +dev = ["Sphinx (>=1.7.2)", "bandit (>=1.5.0)", "flake8 (>=3.5.0)", "flake8-import-order (>=0.0.11)", "pytest (>=5.4.3)", "pytest-cov (>=2.10.0)", "setuptools", "sphinxcontrib-programoutput (>=0.11)", "twine", "wheel"] + +[[package]] +name = "importlib-resources" +version = "5.12.0" +description = "Read resources from Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, + {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, +] + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + +[[package]] +name = "inflect" +version = "5.6.2" +description = "Correctly generate plurals, singular nouns, ordinals, indefinite articles; convert numbers to words" +optional = false +python-versions = ">=3.7" +files = [ + {file = "inflect-5.6.2-py3-none-any.whl", hash = "sha256:b45d91a4a28a4e617ff1821117439b06eaa86e2a4573154af0149e9be6687238"}, + {file = "inflect-5.6.2.tar.gz", hash = "sha256:aadc7ed73928f5e014129794bbac03058cca35d0a973a5fc4eb45c7fa26005f9"}, +] + +[package.extras] +docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"] +testing = ["pygments", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -235,6 +867,165 @@ pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib" plugins = ["setuptools"] requirements-deprecated-finder = ["pip-api", "pipreqs"] +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jsonschema" +version = "4.17.3" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, +] + +[package.dependencies] +attrs = ">=17.4.0" +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "jsonschema-spec" +version = "0.1.6" +description = "JSONSchema Spec with object-oriented paths" +optional = false +python-versions = ">=3.7.0,<4.0.0" +files = [ + {file = "jsonschema_spec-0.1.6-py3-none-any.whl", hash = "sha256:f2206d18c89d1824c1f775ba14ed039743b41a9167bd2c5bdb774b66b3ca0bbf"}, + {file = "jsonschema_spec-0.1.6.tar.gz", hash = "sha256:90215863b56e212086641956b20127ccbf6d8a3a38343dad01d6a74d19482f76"}, +] + +[package.dependencies] +jsonschema = ">=4.0.0,<4.18.0" +pathable = ">=0.4.1,<0.5.0" +PyYAML = ">=5.1" +requests = ">=2.31.0,<3.0.0" + +[[package]] +name = "lazy-object-proxy" +version = "1.9.0" +description = "A fast and thorough lazy object proxy." +optional = false +python-versions = ">=3.7" +files = [ + {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, +] + +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + [[package]] name = "mccabe" version = "0.7.0" @@ -248,37 +1039,37 @@ files = [ [[package]] name = "mypy" -version = "1.3.0" +version = "1.4.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eb485cea53f4f5284e5baf92902cd0088b24984f4209e25981cc359d64448d"}, - {file = "mypy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c99c3ecf223cf2952638da9cd82793d8f3c0c5fa8b6ae2b2d9ed1e1ff51ba85"}, - {file = "mypy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:550a8b3a19bb6589679a7c3c31f64312e7ff482a816c96e0cecec9ad3a7564dd"}, - {file = "mypy-1.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cbc07246253b9e3d7d74c9ff948cd0fd7a71afcc2b77c7f0a59c26e9395cb152"}, - {file = "mypy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:a22435632710a4fcf8acf86cbd0d69f68ac389a3892cb23fbad176d1cddaf228"}, - {file = "mypy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6e33bb8b2613614a33dff70565f4c803f889ebd2f859466e42b46e1df76018dd"}, - {file = "mypy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d23370d2a6b7a71dc65d1266f9a34e4cde9e8e21511322415db4b26f46f6b8c"}, - {file = "mypy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658fe7b674769a0770d4b26cb4d6f005e88a442fe82446f020be8e5f5efb2fae"}, - {file = "mypy-1.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d29e324cdda61daaec2336c42512e59c7c375340bd202efa1fe0f7b8f8ca"}, - {file = "mypy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:d0b6c62206e04061e27009481cb0ec966f7d6172b5b936f3ead3d74f29fe3dcf"}, - {file = "mypy-1.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:76ec771e2342f1b558c36d49900dfe81d140361dd0d2df6cd71b3db1be155409"}, - {file = "mypy-1.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc95f8386314272bbc817026f8ce8f4f0d2ef7ae44f947c4664efac9adec929"}, - {file = "mypy-1.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:faff86aa10c1aa4a10e1a301de160f3d8fc8703b88c7e98de46b531ff1276a9a"}, - {file = "mypy-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:8c5979d0deb27e0f4479bee18ea0f83732a893e81b78e62e2dda3e7e518c92ee"}, - {file = "mypy-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c5d2cc54175bab47011b09688b418db71403aefad07cbcd62d44010543fc143f"}, - {file = "mypy-1.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:87df44954c31d86df96c8bd6e80dfcd773473e877ac6176a8e29898bfb3501cb"}, - {file = "mypy-1.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:473117e310febe632ddf10e745a355714e771ffe534f06db40702775056614c4"}, - {file = "mypy-1.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:74bc9b6e0e79808bf8678d7678b2ae3736ea72d56eede3820bd3849823e7f305"}, - {file = "mypy-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:44797d031a41516fcf5cbfa652265bb994e53e51994c1bd649ffcd0c3a7eccbf"}, - {file = "mypy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ddae0f39ca146972ff6bb4399f3b2943884a774b8771ea0a8f50e971f5ea5ba8"}, - {file = "mypy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c4c42c60a8103ead4c1c060ac3cdd3ff01e18fddce6f1016e08939647a0e703"}, - {file = "mypy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e86c2c6852f62f8f2b24cb7a613ebe8e0c7dc1402c61d36a609174f63e0ff017"}, - {file = "mypy-1.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f9dca1e257d4cc129517779226753dbefb4f2266c4eaad610fc15c6a7e14283e"}, - {file = "mypy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:95d8d31a7713510685b05fbb18d6ac287a56c8f6554d88c19e73f724a445448a"}, - {file = "mypy-1.3.0-py3-none-any.whl", hash = "sha256:a8763e72d5d9574d45ce5881962bc8e9046bf7b375b0abf031f3e6811732a897"}, - {file = "mypy-1.3.0.tar.gz", hash = "sha256:e1f4d16e296f5135624b34e8fb741eb0eadedca90862405b1f1fde2040b9bd11"}, + {file = "mypy-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3af348e0925a59213244f28c7c0c3a2c2088b4ba2fe9d6c8d4fbb0aba0b7d05"}, + {file = "mypy-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0b2e0da7ff9dd8d2066d093d35a169305fc4e38db378281fce096768a3dbdbf"}, + {file = "mypy-1.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210fe0f39ec5be45dd9d0de253cb79245f0a6f27631d62e0c9c7988be7152965"}, + {file = "mypy-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f7a5971490fd4a5a436e143105a1f78fa8b3fe95b30fff2a77542b4f3227a01f"}, + {file = "mypy-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:50f65f0e9985f1e50040e603baebab83efed9eb37e15a22a4246fa7cd660f981"}, + {file = "mypy-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b1b5c875fcf3e7217a3de7f708166f641ca154b589664c44a6fd6d9f17d9e7e"}, + {file = "mypy-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b4c734d947e761c7ceb1f09a98359dd5666460acbc39f7d0a6b6beec373c5840"}, + {file = "mypy-1.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5984a8d13d35624e3b235a793c814433d810acba9eeefe665cdfed3d08bc3af"}, + {file = "mypy-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0f98973e39e4a98709546a9afd82e1ffcc50c6ec9ce6f7870f33ebbf0bd4f26d"}, + {file = "mypy-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:19d42b08c7532d736a7e0fb29525855e355fa51fd6aef4f9bbc80749ff64b1a2"}, + {file = "mypy-1.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6ba9a69172abaa73910643744d3848877d6aac4a20c41742027dcfd8d78f05d9"}, + {file = "mypy-1.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a34eed094c16cad0f6b0d889811592c7a9b7acf10d10a7356349e325d8704b4f"}, + {file = "mypy-1.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:53c2a1fed81e05ded10a4557fe12bae05b9ecf9153f162c662a71d924d504135"}, + {file = "mypy-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bba57b4d2328740749f676807fcf3036e9de723530781405cc5a5e41fc6e20de"}, + {file = "mypy-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:653863c75f0dbb687d92eb0d4bd9fe7047d096987ecac93bb7b1bc336de48ebd"}, + {file = "mypy-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7461469e163f87a087a5e7aa224102a30f037c11a096a0ceeb721cb0dce274c8"}, + {file = "mypy-1.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cf0ca95e4b8adeaf07815a78b4096b65adf64ea7871b39a2116c19497fcd0dd"}, + {file = "mypy-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:94a81b9354545123feb1a99b960faeff9e1fa204fce47e0042335b473d71530d"}, + {file = "mypy-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:67242d5b28ed0fa88edd8f880aed24da481929467fdbca6487167cb5e3fd31ff"}, + {file = "mypy-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3f2b353eebef669529d9bd5ae3566905a685ae98b3af3aad7476d0d519714758"}, + {file = "mypy-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:62bf18d97c6b089f77f0067b4e321db089d8520cdeefc6ae3ec0f873621c22e5"}, + {file = "mypy-1.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca33ab70a4aaa75bb01086a0b04f0ba8441e51e06fc57e28585176b08cad533b"}, + {file = "mypy-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5a0ee54c2cb0f957f8a6f41794d68f1a7e32b9968675ade5846f538504856d42"}, + {file = "mypy-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:6c34d43e3d54ad05024576aef28081d9d0580f6fa7f131255f54020eb12f5352"}, + {file = "mypy-1.4.0-py3-none-any.whl", hash = "sha256:f051ca656be0c179c735a4c3193f307d34c92fdc4908d44fd4516fbe8b10567d"}, + {file = "mypy-1.4.0.tar.gz", hash = "sha256:de1e7e68148a213036276d1f5303b3836ad9a774188961eb2684eddff593b042"}, ] [package.dependencies] @@ -303,6 +1094,128 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "openapi-schema-validator" +version = "0.4.4" +description = "OpenAPI schema validation for Python" +optional = false +python-versions = ">=3.7.0,<4.0.0" +files = [ + {file = "openapi_schema_validator-0.4.4-py3-none-any.whl", hash = "sha256:79f37f38ef9fd5206b924ed7a6f382cea7b649b3b56383c47f1906082b7b9015"}, + {file = "openapi_schema_validator-0.4.4.tar.gz", hash = "sha256:c573e2be2c783abae56c5a1486ab716ca96e09d1c3eab56020d1dc680aa57bf8"}, +] + +[package.dependencies] +jsonschema = ">=4.0.0,<4.18.0" +rfc3339-validator = "*" + +[package.extras] +docs = ["sphinx (>=5.3.0,<6.0.0)", "sphinx-immaterial (>=0.11.0,<0.12.0)"] + +[[package]] +name = "openapi-spec-validator" +version = "0.5.2" +description = "OpenAPI 2.0 (aka Swagger) and OpenAPI 3 spec validator" +optional = false +python-versions = ">=3.7.0,<4.0.0" +files = [ + {file = "openapi_spec_validator-0.5.2-py3-none-any.whl", hash = "sha256:1f8db08ecbcf4ec8c558d65b65b3b7b428f81da6642f2f163e992ae3e17b229c"}, + {file = "openapi_spec_validator-0.5.2.tar.gz", hash = "sha256:ebed7f1c567780859402ad64b128e17f519d15f605f1b41d1e9a4a7a1690be07"}, +] + +[package.dependencies] +importlib-resources = {version = ">=5.8.0,<6.0.0", markers = "python_version < \"3.9\""} +jsonschema = ">=4.0.0,<5.0.0" +jsonschema-spec = ">=0.1.1,<0.2.0" +lazy-object-proxy = ">=1.7.1,<2.0.0" +openapi-schema-validator = ">=0.3.2,<0.5" + +[package.extras] +requests = ["requests"] + +[[package]] +name = "openpyxl" +version = "3.1.2" +description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +optional = false +python-versions = ">=3.6" +files = [ + {file = "openpyxl-3.1.2-py2.py3-none-any.whl", hash = "sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5"}, + {file = "openpyxl-3.1.2.tar.gz", hash = "sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184"}, +] + +[package.dependencies] +et-xmlfile = "*" + +[[package]] +name = "orderedmultidict" +version = "1.0.1" +description = "Ordered Multivalue Dictionary" +optional = false +python-versions = "*" +files = [ + {file = "orderedmultidict-1.0.1-py2.py3-none-any.whl", hash = "sha256:43c839a17ee3cdd62234c47deca1a8508a3f2ca1d0678a3bf791c87cf84adbf3"}, + {file = "orderedmultidict-1.0.1.tar.gz", hash = "sha256:04070bbb5e87291cc9bfa51df413677faf2141c73c61d2a5f7b26bea3cd882ad"}, +] + +[package.dependencies] +six = ">=1.8.0" + +[[package]] +name = "orjson" +version = "3.9.1" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.7" +files = [ + {file = "orjson-3.9.1-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c4434b7b786fdc394b95d029fb99949d7c2b05bbd4bf5cb5e3906be96ffeee3b"}, + {file = "orjson-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09faf14f74ed47e773fa56833be118e04aa534956f661eb491522970b7478e3b"}, + {file = "orjson-3.9.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:503eb86a8d53a187fe66aa80c69295a3ca35475804da89a9547e4fce5f803822"}, + {file = "orjson-3.9.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:20f2804b5a1dbd3609c086041bd243519224d47716efd7429db6c03ed28b7cc3"}, + {file = "orjson-3.9.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fd828e0656615a711c4cc4da70f3cac142e66a6703ba876c20156a14e28e3fa"}, + {file = "orjson-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec53d648176f873203b9c700a0abacab33ca1ab595066e9d616f98cdc56f4434"}, + {file = "orjson-3.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e186ae76b0d97c505500664193ddf508c13c1e675d9b25f1f4414a7606100da6"}, + {file = "orjson-3.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d4edee78503016f4df30aeede0d999b3cb11fb56f47e9db0e487bce0aaca9285"}, + {file = "orjson-3.9.1-cp310-none-win_amd64.whl", hash = "sha256:a4cc5d21e68af982d9a2528ac61e604f092c60eed27aef3324969c68f182ec7e"}, + {file = "orjson-3.9.1-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:761b6efd33c49de20dd73ce64cc59da62c0dab10aa6015f582680e0663cc792c"}, + {file = "orjson-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31229f9d0b8dc2ef7ee7e4393f2e4433a28e16582d4b25afbfccc9d68dc768f8"}, + {file = "orjson-3.9.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0b7ab18d55ecb1de543d452f0a5f8094b52282b916aa4097ac11a4c79f317b86"}, + {file = "orjson-3.9.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db774344c39041f4801c7dfe03483df9203cbd6c84e601a65908e5552228dd25"}, + {file = "orjson-3.9.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae47ef8c0fe89c4677db7e9e1fb2093ca6e66c3acbee5442d84d74e727edad5e"}, + {file = "orjson-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:103952c21575b9805803c98add2eaecd005580a1e746292ed2ec0d76dd3b9746"}, + {file = "orjson-3.9.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2cb0121e6f2c9da3eddf049b99b95fef0adf8480ea7cb544ce858706cdf916eb"}, + {file = "orjson-3.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:24d4ddaa2876e657c0fd32902b5c451fd2afc35159d66a58da7837357044b8c2"}, + {file = "orjson-3.9.1-cp311-none-win_amd64.whl", hash = "sha256:0b53b5f72cf536dd8aa4fc4c95e7e09a7adb119f8ff8ee6cc60f735d7740ad6a"}, + {file = "orjson-3.9.1-cp37-cp37m-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d4b68d01a506242316a07f1d2f29fb0a8b36cee30a7c35076f1ef59dce0890c1"}, + {file = "orjson-3.9.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9dd4abe6c6fd352f00f4246d85228f6a9847d0cc14f4d54ee553718c225388f"}, + {file = "orjson-3.9.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e20bca5e13041e31ceba7a09bf142e6d63c8a7467f5a9c974f8c13377c75af2"}, + {file = "orjson-3.9.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d8ae0467d01eb1e4bcffef4486d964bfd1c2e608103e75f7074ed34be5df48cc"}, + {file = "orjson-3.9.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:06f6ab4697fab090517f295915318763a97a12ee8186054adf21c1e6f6abbd3d"}, + {file = "orjson-3.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8515867713301fa065c58ec4c9053ba1a22c35113ab4acad555317b8fd802e50"}, + {file = "orjson-3.9.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:393d0697d1dfa18d27d193e980c04fdfb672c87f7765b87952f550521e21b627"}, + {file = "orjson-3.9.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d96747662d3666f79119e5d28c124e7d356c7dc195cd4b09faea4031c9079dc9"}, + {file = "orjson-3.9.1-cp37-none-win_amd64.whl", hash = "sha256:6d173d3921dd58a068c88ec22baea7dbc87a137411501618b1292a9d6252318e"}, + {file = "orjson-3.9.1-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d1c2b0b4246c992ce2529fc610a446b945f1429445ece1c1f826a234c829a918"}, + {file = "orjson-3.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19f70ba1f441e1c4bb1a581f0baa092e8b3e3ce5b2aac2e1e090f0ac097966da"}, + {file = "orjson-3.9.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:375d65f002e686212aac42680aed044872c45ee4bc656cf63d4a215137a6124a"}, + {file = "orjson-3.9.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4751cee4a7b1daeacb90a7f5adf2170ccab893c3ab7c5cea58b45a13f89b30b3"}, + {file = "orjson-3.9.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d9a2a4b2302d5ebc3695498ebc305c3568e5ad4f3501eb30a6405a32d8af22"}, + {file = "orjson-3.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46b4facc32643b2689dfc292c0c463985dac4b6ab504799cf51fc3c6959ed668"}, + {file = "orjson-3.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ec7c8a0f1bf35da0d5fd14f8956f3b82a9a6918a3c6963d718dfd414d6d3b604"}, + {file = "orjson-3.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3a40b0fbe06ccd4d6a99e523d20b47985655bcada8d1eba485b1b32a43e4904"}, + {file = "orjson-3.9.1-cp38-none-win_amd64.whl", hash = "sha256:402f9d3edfec4560a98880224ec10eba4c5f7b4791e4bc0d4f4d8df5faf2a006"}, + {file = "orjson-3.9.1-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:49c0d78dcd34626e2e934f1192d7c052b94e0ecadc5f386fd2bda6d2e03dadf5"}, + {file = "orjson-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:125f63e56d38393daa0a1a6dc6fedefca16c538614b66ea5997c3bd3af35ef26"}, + {file = "orjson-3.9.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:08927970365d2e1f3ce4894f9ff928a7b865d53f26768f1bbdd85dd4fee3e966"}, + {file = "orjson-3.9.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9a744e212d4780ecd67f4b6b128b2e727bee1df03e7059cddb2dfe1083e7dc4"}, + {file = "orjson-3.9.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d1dbf36db7240c61eec98c8d21545d671bce70be0730deb2c0d772e06b71af3"}, + {file = "orjson-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80a1e384626f76b66df615f7bb622a79a25c166d08c5d2151ffd41f24c4cc104"}, + {file = "orjson-3.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:15d28872fb055bf17ffca913826e618af61b2f689d2b170f72ecae1a86f80d52"}, + {file = "orjson-3.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1e4d905338f9ef32c67566929dfbfbb23cc80287af8a2c38930fb0eda3d40b76"}, + {file = "orjson-3.9.1-cp39-none-win_amd64.whl", hash = "sha256:48a27da6c7306965846565cc385611d03382bbd84120008653aa2f6741e2105d"}, + {file = "orjson-3.9.1.tar.gz", hash = "sha256:db373a25ec4a4fccf8186f9a72a1b3442837e40807a736a815ab42481e83b7d0"}, +] + [[package]] name = "packaging" version = "23.1" @@ -314,6 +1227,38 @@ files = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] +[[package]] +name = "paramiko" +version = "3.2.0" +description = "SSH2 protocol library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "paramiko-3.2.0-py3-none-any.whl", hash = "sha256:df0f9dd8903bc50f2e10580af687f3015bf592a377cd438d2ec9546467a14eb8"}, + {file = "paramiko-3.2.0.tar.gz", hash = "sha256:93cdce625a8a1dc12204439d45033f3261bdb2c201648cfcdc06f9fd0f94ec29"}, +] + +[package.dependencies] +bcrypt = ">=3.2" +cryptography = ">=3.3" +pynacl = ">=1.5" + +[package.extras] +all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] +gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] +invoke = ["invoke (>=2.0)"] + +[[package]] +name = "pathable" +version = "0.4.3" +description = "Object-oriented paths" +optional = false +python-versions = ">=3.7.0,<4.0.0" +files = [ + {file = "pathable-0.4.3-py3-none-any.whl", hash = "sha256:cdd7b1f9d7d5c8b8d3315dbf5a86b2596053ae845f056f57d97c0eefff84da14"}, + {file = "pathable-0.4.3.tar.gz", hash = "sha256:5c869d315be50776cc8a993f3af43e0c60dc01506b399643f919034ebf4cdcab"}, +] + [[package]] name = "pathspec" version = "0.11.1" @@ -325,15 +1270,26 @@ files = [ {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, ] +[[package]] +name = "pkgutil-resolve-name" +version = "1.3.10" +description = "Resolve a name to an object." +optional = false +python-versions = ">=3.6" +files = [ + {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, + {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, +] + [[package]] name = "platformdirs" -version = "3.5.3" +version = "3.7.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.5.3-py3-none-any.whl", hash = "sha256:0ade98a4895e87dc51d47151f7d2ec290365a585151d97b4d8d6312ed6132fed"}, - {file = "platformdirs-3.5.3.tar.gz", hash = "sha256:e48fabd87db8f3a7df7150a4a5ea22c546ee8bc39bc2473244730d4b56d2cc4e"}, + {file = "platformdirs-3.7.0-py3-none-any.whl", hash = "sha256:cfd065ba43133ff103ab3bd10aecb095c2a0035fcd1f07217c9376900d94ba07"}, + {file = "platformdirs-3.7.0.tar.gz", hash = "sha256:87fbf6473e87c078d536980ba970a472422e94f17b752cfad17024c18876d481"}, ] [package.extras] @@ -342,19 +1298,45 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest- [[package]] name = "pluggy" -version = "1.0.0" +version = "1.2.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, ] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "prance" +version = "0.22.2.22.0" +description = "Resolving Swagger/OpenAPI 2.0 and 3.0.0 Parser" +optional = false +python-versions = ">=3.8" +files = [ + {file = "prance-0.22.2.22.0-py3-none-any.whl", hash = "sha256:57deeb67b7e93ef27c1c17845bf3ccb4af288ccfb5748c7e01779c01a8507f27"}, + {file = "prance-0.22.2.22.0.tar.gz", hash = "sha256:9a83f8a4f5fe0f2d896d238d4bec6b5788b10b94155414b3d88c21c1579b85bf"}, +] + +[package.dependencies] +chardet = ">=3.0" +packaging = ">=21.3" +requests = ">=2.25" +"ruamel.yaml" = ">=0.17.10" +six = ">=1.15,<2.0" + +[package.extras] +cli = ["click (>=7.0)"] +dev = ["bumpversion (>=0.6)", "pytest (>=6.1)", "pytest-cov (>=2.11)", "sphinx (>=3.4)", "towncrier (>=19.2)", "tox (>=3.4)"] +flex = ["flex (>=6.13,<7.0)"] +icu = ["PyICU (>=2.4,<3.0)"] +osv = ["openapi-spec-validator (>=0.5.1,<0.6.0)"] +ssv = ["swagger-spec-validator (>=2.4,<3.0)"] + [[package]] name = "pycodestyle" version = "2.10.0" @@ -366,6 +1348,70 @@ files = [ {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, ] +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] + +[[package]] +name = "pydantic" +version = "1.10.9" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e692dec4a40bfb40ca530e07805b1208c1de071a18d26af4a2a0d79015b352ca"}, + {file = "pydantic-1.10.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3c52eb595db83e189419bf337b59154bdcca642ee4b2a09e5d7797e41ace783f"}, + {file = "pydantic-1.10.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:939328fd539b8d0edf244327398a667b6b140afd3bf7e347cf9813c736211896"}, + {file = "pydantic-1.10.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b48d3d634bca23b172f47f2335c617d3fcb4b3ba18481c96b7943a4c634f5c8d"}, + {file = "pydantic-1.10.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f0b7628fb8efe60fe66fd4adadd7ad2304014770cdc1f4934db41fe46cc8825f"}, + {file = "pydantic-1.10.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e1aa5c2410769ca28aa9a7841b80d9d9a1c5f223928ca8bec7e7c9a34d26b1d4"}, + {file = "pydantic-1.10.9-cp310-cp310-win_amd64.whl", hash = "sha256:eec39224b2b2e861259d6f3c8b6290d4e0fbdce147adb797484a42278a1a486f"}, + {file = "pydantic-1.10.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d111a21bbbfd85c17248130deac02bbd9b5e20b303338e0dbe0faa78330e37e0"}, + {file = "pydantic-1.10.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e9aec8627a1a6823fc62fb96480abe3eb10168fd0d859ee3d3b395105ae19a7"}, + {file = "pydantic-1.10.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07293ab08e7b4d3c9d7de4949a0ea571f11e4557d19ea24dd3ae0c524c0c334d"}, + {file = "pydantic-1.10.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ee829b86ce984261d99ff2fd6e88f2230068d96c2a582f29583ed602ef3fc2c"}, + {file = "pydantic-1.10.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4b466a23009ff5cdd7076eb56aca537c745ca491293cc38e72bf1e0e00de5b91"}, + {file = "pydantic-1.10.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7847ca62e581e6088d9000f3c497267868ca2fa89432714e21a4fb33a04d52e8"}, + {file = "pydantic-1.10.9-cp311-cp311-win_amd64.whl", hash = "sha256:7845b31959468bc5b78d7b95ec52fe5be32b55d0d09983a877cca6aedc51068f"}, + {file = "pydantic-1.10.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:517a681919bf880ce1dac7e5bc0c3af1e58ba118fd774da2ffcd93c5f96eaece"}, + {file = "pydantic-1.10.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67195274fd27780f15c4c372f4ba9a5c02dad6d50647b917b6a92bf00b3d301a"}, + {file = "pydantic-1.10.9-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2196c06484da2b3fded1ab6dbe182bdabeb09f6318b7fdc412609ee2b564c49a"}, + {file = "pydantic-1.10.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6257bb45ad78abacda13f15bde5886efd6bf549dd71085e64b8dcf9919c38b60"}, + {file = "pydantic-1.10.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3283b574b01e8dbc982080d8287c968489d25329a463b29a90d4157de4f2baaf"}, + {file = "pydantic-1.10.9-cp37-cp37m-win_amd64.whl", hash = "sha256:5f8bbaf4013b9a50e8100333cc4e3fa2f81214033e05ac5aa44fa24a98670a29"}, + {file = "pydantic-1.10.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b9cd67fb763248cbe38f0593cd8611bfe4b8ad82acb3bdf2b0898c23415a1f82"}, + {file = "pydantic-1.10.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f50e1764ce9353be67267e7fd0da08349397c7db17a562ad036aa7c8f4adfdb6"}, + {file = "pydantic-1.10.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73ef93e5e1d3c8e83f1ff2e7fdd026d9e063c7e089394869a6e2985696693766"}, + {file = "pydantic-1.10.9-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:128d9453d92e6e81e881dd7e2484e08d8b164da5507f62d06ceecf84bf2e21d3"}, + {file = "pydantic-1.10.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ad428e92ab68798d9326bb3e5515bc927444a3d71a93b4a2ca02a8a5d795c572"}, + {file = "pydantic-1.10.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fab81a92f42d6d525dd47ced310b0c3e10c416bbfae5d59523e63ea22f82b31e"}, + {file = "pydantic-1.10.9-cp38-cp38-win_amd64.whl", hash = "sha256:963671eda0b6ba6926d8fc759e3e10335e1dc1b71ff2a43ed2efd6996634dafb"}, + {file = "pydantic-1.10.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:970b1bdc6243ef663ba5c7e36ac9ab1f2bfecb8ad297c9824b542d41a750b298"}, + {file = "pydantic-1.10.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7e1d5290044f620f80cf1c969c542a5468f3656de47b41aa78100c5baa2b8276"}, + {file = "pydantic-1.10.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83fcff3c7df7adff880622a98022626f4f6dbce6639a88a15a3ce0f96466cb60"}, + {file = "pydantic-1.10.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0da48717dc9495d3a8f215e0d012599db6b8092db02acac5e0d58a65248ec5bc"}, + {file = "pydantic-1.10.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0a2aabdc73c2a5960e87c3ffebca6ccde88665616d1fd6d3db3178ef427b267a"}, + {file = "pydantic-1.10.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9863b9420d99dfa9c064042304868e8ba08e89081428a1c471858aa2af6f57c4"}, + {file = "pydantic-1.10.9-cp39-cp39-win_amd64.whl", hash = "sha256:e7c9900b43ac14110efa977be3da28931ffc74c27e96ee89fbcaaf0b0fe338e1"}, + {file = "pydantic-1.10.9-py3-none-any.whl", hash = "sha256:6cafde02f6699ce4ff643417d1a9223716ec25e228ddc3b436fe7e2d25a1f305"}, + {file = "pydantic-1.10.9.tar.gz", hash = "sha256:95c70da2cd3b6ddf3b9645ecaa8d98f3d80c606624b6d245558d202cd23ea3be"}, +] + +[package.dependencies] +email-validator = {version = ">=1.0.3", optional = true, markers = "extra == \"email\""} +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + [[package]] name = "pyflakes" version = "3.0.1" @@ -377,6 +1423,82 @@ files = [ {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, ] +[[package]] +name = "pynacl" +version = "1.5.0" +description = "Python binding to the Networking and Cryptography (NaCl) library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"}, + {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"}, + {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"}, + {file = "PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"}, + {file = "PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"}, + {file = "PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"}, +] + +[package.dependencies] +cffi = ">=1.4.1" + +[package.extras] +docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] +tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] + +[[package]] +name = "pyrsistent" +version = "0.19.3" +description = "Persistent/Functional/Immutable data structures" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, + {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, + {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, + {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, + {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, + {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, +] + +[[package]] +name = "pysnooper" +version = "1.1.1" +description = "A poor man's debugger for Python." +optional = false +python-versions = "*" +files = [ + {file = "PySnooper-1.1.1-py2.py3-none-any.whl", hash = "sha256:378f13d731a3e04d3d0350e5f295bdd0f1b49fc8a8b8bf2067fe1e5290bd20be"}, + {file = "PySnooper-1.1.1.tar.gz", hash = "sha256:d17dc91cca1593c10230dce45e46b1d3ff0f8910f0c38e941edf6ba1260b3820"}, +] + +[package.extras] +tests = ["pytest"] + [[package]] name = "pytest" version = "7.3.2" @@ -417,6 +1539,220 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +[[package]] +name = "python-dotenv" +version = "1.0.0" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, + {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "python-frontmatter" +version = "1.0.0" +description = "Parse and manage posts with YAML (or other) frontmatter" +optional = false +python-versions = "*" +files = [ + {file = "python-frontmatter-1.0.0.tar.gz", hash = "sha256:e98152e977225ddafea6f01f40b4b0f1de175766322004c826ca99842d19a7cd"}, + {file = "python_frontmatter-1.0.0-py3-none-any.whl", hash = "sha256:766ae75f1b301ffc5fe3494339147e0fd80bc3deff3d7590a93991978b579b08"}, +] + +[package.dependencies] +PyYAML = "*" + +[package.extras] +docs = ["sphinx"] +test = ["pyaml", "pytest", "toml"] + +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] + +[[package]] +name = "pyyaml" +version = "6.0" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, + {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, + {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +description = "A pure python RFC3339 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, + {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "ruamel-yaml" +version = "0.17.32" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +optional = false +python-versions = ">=3" +files = [ + {file = "ruamel.yaml-0.17.32-py3-none-any.whl", hash = "sha256:23cd2ed620231677564646b0c6a89d138b6822a0d78656df7abda5879ec4f447"}, + {file = "ruamel.yaml-0.17.32.tar.gz", hash = "sha256:ec939063761914e14542972a5cba6d33c23b0859ab6342f61cf070cfc600efc2"}, +] + +[package.dependencies] +"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.12\""} + +[package.extras] +docs = ["ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.7" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +optional = false +python-versions = ">=3.5" +files = [ + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5859983f26d8cd7bb5c287ef452e8aacc86501487634573d260968f753e1d71"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:debc87a9516b237d0466a711b18b6ebeb17ba9f391eb7f91c649c5c4ec5006c7"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:df5828871e6648db72d1c19b4bd24819b80a755c4541d3409f0f7acd0f335c80"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:efa08d63ef03d079dcae1dfe334f6c8847ba8b645d08df286358b1f5293d24ab"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:370445fd795706fd291ab00c9df38a0caed0f17a6fb46b0f607668ecb16ce763"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win32.whl", hash = "sha256:ecdf1a604009bd35c674b9225a8fa609e0282d9b896c03dd441a91e5f53b534e"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win_amd64.whl", hash = "sha256:f34019dced51047d6f70cb9383b2ae2853b7fc4dce65129a5acd49f4f9256646"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa261c29a5545adfef9296b7e33941f46aa5bbd21164228e833412af4c9c75f"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f01da5790e95815eb5a8a138508c01c758e5f5bc0ce4286c4f7028b8dd7ac3d0"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:40d030e2329ce5286d6b231b8726959ebbe0404c92f0a578c0e2482182e38282"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c3ca1fbba4ae962521e5eb66d72998b51f0f4d0f608d3c0347a48e1af262efa7"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win32.whl", hash = "sha256:7bdb4c06b063f6fd55e472e201317a3bb6cdeeee5d5a38512ea5c01e1acbdd93"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:be2a7ad8fd8f7442b24323d24ba0b56c51219513cfa45b9ada3b87b76c374d4b"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91a789b4aa0097b78c93e3dc4b40040ba55bef518f84a40d4442f713b4094acb"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:99e77daab5d13a48a4054803d052ff40780278240a902b880dd37a51ba01a307"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3243f48ecd450eddadc2d11b5feb08aca941b5cd98c9b1db14b2fd128be8c697"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8831a2cedcd0f0927f788c5bdf6567d9dc9cc235646a434986a852af1cb54b4b"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win32.whl", hash = "sha256:3110a99e0f94a4a3470ff67fc20d3f96c25b13d24c6980ff841e82bafe827cac"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:92460ce908546ab69770b2e576e4f99fbb4ce6ab4b245345a3869a0a0410488f"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5bc0667c1eb8f83a3752b71b9c4ba55ef7c7058ae57022dd9b29065186a113d9"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:4a4d8d417868d68b979076a9be6a38c676eca060785abaa6709c7b31593c35d1"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf9a6bc4a0221538b1a7de3ed7bca4c93c02346853f44e1cd764be0023cd3640"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a7b301ff08055d73223058b5c46c55638917f04d21577c95e00e0c4d79201a6b"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win32.whl", hash = "sha256:d5e51e2901ec2366b79f16c2299a03e74ba4531ddcfacc1416639c557aef0ad8"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, + {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, +] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + [[package]] name = "smmap" version = "5.0.0" @@ -428,6 +1764,28 @@ files = [ {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, ] +[[package]] +name = "sniffio" +version = "1.3.0" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, + {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, +] + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + [[package]] name = "tomli" version = "2.0.1" @@ -450,7 +1808,39 @@ files = [ {file = "typing_extensions-4.6.3.tar.gz", hash = "sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"}, ] +[[package]] +name = "urllib3" +version = "2.0.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.7" +files = [ + {file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"}, + {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "zipp" +version = "3.15.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.7" +files = [ + {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, + {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] + [metadata] lock-version = "2.0" python-versions = "^3.8.1" -content-hash = "941637ab784061d40797c5bb82a35a0af6b224709d59b1f0e00aa451728b7538" +content-hash = "7b26b9e0067e2558ba8512a6aa6707dfd45a5f4d3a957148626d044a1c59e8c8" diff --git a/pyproject.toml b/pyproject.toml index 65db5265..84feea3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ trestle-bot = "trestlebot.cli:run" [tool.poetry.dependencies] python = '^3.8.1' gitpython = "^3.1.31" +compliance-trestle = "^2.1.1" [tool.poetry.group.dev.dependencies] flake8 = "^6.0.0" diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..eea79001 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,76 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Test fixtures""" + +import argparse +import os +import pathlib +from tempfile import TemporaryDirectory +from typing import Generator, Tuple, TypeVar + +import pytest +from git.repo import Repo +from trestle.common.err import TrestleError +from trestle.core.commands.init import InitCmd + + +T = TypeVar("T") + +YieldFixture = Generator[T, None, None] + +_TEST_CONTENTS = """ +test file +""" + +_TEST_FILENAME = "test.txt" + + +@pytest.fixture +def tmp_repo() -> YieldFixture[Tuple[str, Repo]]: + """Create a temporary git repository""" + with TemporaryDirectory(prefix="trestlebot_tests") as tmpdir: + with open(os.path.join(tmpdir, _TEST_FILENAME), "x", encoding="utf8") as file: + file.write(_TEST_CONTENTS) + repo = Repo.init(tmpdir) + with repo.config_writer() as config: + config.set_value("user", "email", "test@example.com") + config.set_value("user", "name", "Test User") + repo.git.add(all=True) + repo.index.commit("Initial commit") + yield tmpdir, repo + + +@pytest.fixture +def tmp_trestle_dir() -> YieldFixture[str]: + """Create an initialized temporary trestle directory""" + with TemporaryDirectory(prefix="trestlebot_tests") as tmpdir: + tmp_path = pathlib.Path(tmpdir) + try: + args = argparse.Namespace( + verbose=0, + trestle_root=tmp_path, + full=True, + local=False, + govdocs=False, + ) + init = InitCmd() + init._run(args) + except Exception as e: + raise TrestleError( + f"Initialization failed for temporary trestle directory: {e}." + ) + yield tmpdir diff --git a/tests/data/json/simplified_nist_catalog.json b/tests/data/json/simplified_nist_catalog.json new file mode 100644 index 00000000..4af97c1e --- /dev/null +++ b/tests/data/json/simplified_nist_catalog.json @@ -0,0 +1,5225 @@ +{ + "catalog": { + "uuid": "613fca2d-704a-42e7-8e2b-b206fb92b456", + "metadata": { + "title": "Trestle simplified: NIST Special Publication 800-53 Revision 5: Security and Privacy Controls for Federal Information Systems and Organizations", + "last-modified": "2021-06-08T13:57:33.013981-04:00", + "version": "5.0.1", + "oscal-version": "1.0.0", + "props": [ + { + "name": "keywords", + "value": "assurance; availability; computer security; confidentiality; control; cybersecurity; FISMA; information security; information system; integrity; personally identifiable information; Privacy Act; privacy controls; privacy functions; privacy requirements; Risk Management Framework; security controls; security functions; security requirements; system; system security." + } + ], + "links": [ + { + "href": "#c3397cc9-83c6-4459-adb2-836739dc1b94", + "rel": "alternate" + }, + { + "href": "#f7cf488d-bc64-4a91-a994-810e153ee481", + "rel": "canonical" + } + ], + "roles": [ + { + "id": "creator", + "title": "Document creator" + }, + { + "id": "contact", + "title": "Contact" + } + ], + "parties": [ + { + "uuid": "41a93829-b76b-43ec-b9e7-250553511549", + "type": "organization", + "name": "Joint Task Force, Interagency Working Group", + "email-addresses": [ + "sec-cert@nist.gov" + ], + "addresses": [ + { + "addr-lines": [ + "National Institute of Standards and Technology", + "Attn: Computer Security Division" + ], + "city": "Gaithersburg", + "state": "MD", + "postal-code": "20899-8930" + } + ] + } + ], + "responsible-parties": [ + { + "role-id": "creator", + "party-uuids": [ + "41a93829-b76b-43ec-b9e7-250553511549" + ] + }, + { + "role-id": "contact", + "party-uuids": [ + "41a93829-b76b-43ec-b9e7-250553511549" + ] + } + ] + }, + "params": [ + { + "id": "loose_1", + "label": "loose_1_label", + "values": [ + "loose_1_value" + ] + }, + { + "id": "loose_2", + "label": "loose_2_label", + "values": [ + "loose_2_value" + ] + } + ], + "groups": [ + { + "id": "ac", + "class": "family", + "title": "Access Control", + "controls": [ + { + "id": "ac-1", + "class": "SP800-53", + "title": "Policy and Procedures", + "params": [ + { + "id": "ac-1_prm_1", + "props": [ + { + "name": "param_1_prop", + "value": "prop value" + } + ], + "links": [ + { + "href": "#123456789", + "text": "orig link text" + } + ], + "label": "organization-defined personnel or roles", + "constraints": [ + { + "description": "orig constraint desc" + } + ], + "guidelines": [ + { + "prose": "original guideline" + } + ], + "values": [ + "Param_1_value_in_catalog" + ] + }, + { + "id": "ac-1_prm_2", + "select": { + "how-many": "one-or-more", + "choice": [ + "Organization-level", + "Mission/business process-level", + "System-level" + ] + } + }, + { + "id": "ac-1_prm_3", + "label": "organization-defined official" + }, + { + "id": "ac-1_prm_4", + "label": "organization-defined frequency" + }, + { + "id": "ac-1_prm_5", + "label": "organization-defined events" + }, + { + "id": "ac-1_prm_6", + "label": "organization-defined frequency" + }, + { + "id": "ac-1_prm_7", + "label": "organization-defined events" + } + ], + "props": [ + { + "name": "label", + "value": "AC-1" + }, + { + "name": "sort-id", + "value": "ac-01" + }, + { + "name": "extra_prop", + "value": "extra value" + } + ], + "links": [ + { + "href": "#27847491-5ce1-4f6a-a1e4-9e483782f0ef", + "rel": "reference" + }, + { + "href": "#c7ac44e8-10db-4b64-b2b9-9e32ec1efed0", + "rel": "reference" + }, + { + "href": "#08b07465-dbdc-48d6-8a0b-37279602ac16", + "rel": "reference" + }, + { + "href": "#cec037f3-8aba-4c97-84b4-4082f9e515d2", + "rel": "reference" + }, + { + "href": "#4c0ec2ee-a0d6-428a-9043-4504bc3ade6f", + "rel": "reference" + }, + { + "href": "#7f473f21-fdbf-4a6c-81a1-0ab95919609d", + "rel": "reference" + }, + { + "href": "#ia-1", + "rel": "related" + }, + { + "href": "#pm-9", + "rel": "related" + }, + { + "href": "#pm-24", + "rel": "related" + }, + { + "href": "#ps-8", + "rel": "related" + }, + { + "href": "#si-12", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-1_smt", + "name": "statement", + "prose": "The organization:", + "parts": [ + { + "id": "ac-1_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "a." + } + ], + "prose": "Develop, document, and disseminate to {{ insert: param, ac-1_prm_1 }}:", + "parts": [ + { + "id": "ac-1_smt.a.1", + "name": "item", + "props": [ + { + "name": "label", + "value": "1." + } + ], + "prose": " {{ insert: param, ac-1_prm_2 }} access control policy that:", + "parts": [ + { + "id": "ac-1_smt.a.1.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Addresses purpose, scope, roles, responsibilities, management commitment, coordination among organizational entities, and compliance; and" + }, + { + "id": "ac-1_smt.a.1.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Is consistent with applicable laws, executive orders, directives, regulations, policies, standards, and guidelines; and" + } + ] + }, + { + "id": "ac-1_smt.a.2", + "name": "item", + "props": [ + { + "name": "label", + "value": "2." + } + ], + "prose": "Procedures to facilitate the implementation of the access control policy and the associated access controls;" + } + ] + }, + { + "id": "ac-1_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "b." + } + ], + "prose": "Designate an {{ insert: param, ac-1_prm_3 }} to manage the development, documentation, and dissemination of the access control policy and procedures; and" + }, + { + "id": "ac-1_smt.c", + "name": "item", + "props": [ + { + "name": "label", + "value": "c." + } + ], + "prose": "Review and update the current access control:", + "parts": [ + { + "id": "ac-1_smt.c.1", + "name": "item", + "props": [ + { + "name": "label", + "value": "1." + } + ], + "prose": "Policy {{ insert: param, ac-1_prm_4 }} and following {{ insert: param, ac-1_prm_5 }}; and" + }, + { + "id": "ac-1_smt.c.2", + "name": "item", + "props": [ + { + "name": "label", + "value": "2." + } + ], + "prose": "Procedures {{ insert: param, ac-1_prm_6 }} and following {{ insert: param, ac-1_prm_7 }}." + } + ] + } + ], + "props": [ + { + "name": "prop_in_part", + "value": "value in part" + } + ] + }, + { + "id": "ac-1_gdn", + "name": "guidance", + "prose": "Access control policy and procedures address the controls in the AC family that are implemented within systems and organizations. The risk management strategy is an important factor in establishing such policies and procedures. Policies and procedures contribute to security and privacy assurance. Therefore, it is important that security and privacy programs collaborate on the development of access control policy and procedures. Security and privacy program policies and procedures at the organization level are preferable, in general, and may obviate the need for mission- or system-specific policies and procedures. The policy can be included as part of the general security and privacy policy or be represented by multiple policies reflecting the complex nature of organizations. Procedures can be established for security and privacy programs, for mission or business processes, and for systems, if needed. Procedures describe how the policies or controls are implemented and can be directed at the individual or role that is the object of the procedure. Procedures can be documented in system security and privacy plans or in one or more separate documents. Events that may precipitate an update to access control policy and procedures include assessment or audit findings, security incidents or breaches, or changes in laws, executive orders, directives, regulations, policies, standards, and guidelines. Simply restating controls does not constitute an organizational policy or procedure." + } + ] + }, + { + "id": "ac-2", + "class": "SP800-53", + "title": "Account Management", + "params": [ + { + "id": "ac-2_prm_1", + "label": "organization-defined prerequisites and criteria" + }, + { + "id": "ac-2_prm_2", + "label": "organization-defined attributes (as required)" + }, + { + "id": "ac-2_prm_3", + "label": "organization-defined personnel or roles" + }, + { + "id": "ac-2_prm_4", + "label": "organization-defined policy, procedures, prerequisites, and criteria" + }, + { + "id": "ac-2_prm_5", + "label": "organization-defined personnel or roles" + }, + { + "id": "ac-2_prm_6", + "label": "organization-defined time period" + }, + { + "id": "ac-2_prm_7", + "label": "organization-defined time period" + }, + { + "id": "ac-2_prm_8", + "label": "organization-defined time period" + }, + { + "id": "ac-2_prm_9", + "label": "organization-defined attributes (as required)" + }, + { + "id": "ac-2_prm_10", + "label": "organization-defined frequency" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2" + }, + { + "name": "sort-id", + "value": "ac-02" + } + ], + "links": [ + { + "href": "#2956e175-f674-43f4-b1b9-e074ad9fc39c", + "rel": "reference" + }, + { + "href": "#388a3aa2-5d85-4bad-b8a3-77db80d63c4f", + "rel": "reference" + }, + { + "href": "#53df282b-8b3f-483a-bad1-6a8b8ac00114", + "rel": "reference" + }, + { + "href": "#ac-3", + "rel": "related" + }, + { + "href": "#ac-5", + "rel": "related" + }, + { + "href": "#ac-6", + "rel": "related" + }, + { + "href": "#ac-17", + "rel": "related" + }, + { + "href": "#ac-18", + "rel": "related" + }, + { + "href": "#ac-20", + "rel": "related" + }, + { + "href": "#ac-24", + "rel": "related" + }, + { + "href": "#au-2", + "rel": "related" + }, + { + "href": "#au-12", + "rel": "related" + }, + { + "href": "#cm-5", + "rel": "related" + }, + { + "href": "#ia-2", + "rel": "related" + }, + { + "href": "#ia-4", + "rel": "related" + }, + { + "href": "#ia-5", + "rel": "related" + }, + { + "href": "#ia-8", + "rel": "related" + }, + { + "href": "#ma-3", + "rel": "related" + }, + { + "href": "#ma-5", + "rel": "related" + }, + { + "href": "#pe-2", + "rel": "related" + }, + { + "href": "#pl-4", + "rel": "related" + }, + { + "href": "#ps-2", + "rel": "related" + }, + { + "href": "#ps-4", + "rel": "related" + }, + { + "href": "#ps-5", + "rel": "related" + }, + { + "href": "#ps-7", + "rel": "related" + }, + { + "href": "#pt-2", + "rel": "related" + }, + { + "href": "#pt-3", + "rel": "related" + }, + { + "href": "#sc-7", + "rel": "related" + }, + { + "href": "#sc-12", + "rel": "related" + }, + { + "href": "#sc-13", + "rel": "related" + }, + { + "href": "#sc-37", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-2_smt", + "name": "statement", + "parts": [ + { + "id": "ac-2_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "a." + } + ], + "prose": "Define and document the types of accounts allowed and specifically prohibited for use within the system;" + }, + { + "id": "ac-2_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "b." + } + ], + "prose": "Assign account managers;" + }, + { + "id": "ac-2_smt.c", + "name": "item", + "props": [ + { + "name": "label", + "value": "c." + } + ], + "prose": "Require {{ insert: param, ac-2_prm_1 }} for group and role membership;" + }, + { + "id": "ac-2_smt.d", + "name": "item", + "props": [ + { + "name": "label", + "value": "d." + } + ], + "prose": "Specify:", + "parts": [ + { + "id": "ac-2_smt.d.1", + "name": "item", + "props": [ + { + "name": "label", + "value": "1." + } + ], + "prose": "Authorized users of the system;" + }, + { + "id": "ac-2_smt.d.2", + "name": "item", + "props": [ + { + "name": "label", + "value": "2." + } + ], + "prose": "Group and role membership; and" + }, + { + "id": "ac-2_smt.d.3", + "name": "item", + "props": [ + { + "name": "label", + "value": "3." + } + ], + "prose": "Access authorizations (i.e., privileges) and {{ insert: param, ac-2_prm_2 }} for each account;" + } + ] + }, + { + "id": "ac-2_smt.e", + "name": "item", + "props": [ + { + "name": "label", + "value": "e." + } + ], + "prose": "Require approvals by {{ insert: param, ac-2_prm_3 }} for requests to create accounts;" + }, + { + "id": "ac-2_smt.f", + "name": "item", + "props": [ + { + "name": "label", + "value": "f." + } + ], + "prose": "Create, enable, modify, disable, and remove accounts in accordance with {{ insert: param, ac-2_prm_4 }};" + }, + { + "id": "ac-2_smt.g", + "name": "item", + "props": [ + { + "name": "label", + "value": "g." + } + ], + "prose": "Monitor the use of accounts;" + }, + { + "id": "ac-2_smt.h", + "name": "item", + "props": [ + { + "name": "label", + "value": "h." + } + ], + "prose": "Notify account managers and {{ insert: param, ac-2_prm_5 }} within:", + "parts": [ + { + "id": "ac-2_smt.h.1", + "name": "item", + "props": [ + { + "name": "label", + "value": "1." + } + ], + "prose": " {{ insert: param, ac-2_prm_6 }} when accounts are no longer required;" + }, + { + "id": "ac-2_smt.h.2", + "name": "item", + "props": [ + { + "name": "label", + "value": "2." + } + ], + "prose": " {{ insert: param, ac-2_prm_7 }} when users are terminated or transferred; and" + }, + { + "id": "ac-2_smt.h.3", + "name": "item", + "props": [ + { + "name": "label", + "value": "3." + } + ], + "prose": " {{ insert: param, ac-2_prm_8 }} when system usage or need-to-know changes for an individual;" + } + ] + }, + { + "id": "ac-2_smt.i", + "name": "item", + "props": [ + { + "name": "label", + "value": "i." + } + ], + "prose": "Authorize access to the system based on:", + "parts": [ + { + "id": "ac-2_smt.i.1", + "name": "item", + "props": [ + { + "name": "label", + "value": "1." + } + ], + "prose": "A valid access authorization;" + }, + { + "id": "ac-2_smt.i.2", + "name": "item", + "props": [ + { + "name": "label", + "value": "2." + } + ], + "prose": "Intended system usage; and" + }, + { + "id": "ac-2_smt.i.3", + "name": "item", + "props": [ + { + "name": "label", + "value": "3." + } + ], + "prose": " {{ insert: param, ac-2_prm_9 }};" + } + ] + }, + { + "id": "ac-2_smt.j", + "name": "item", + "props": [ + { + "name": "label", + "value": "j." + } + ], + "prose": "Review accounts for compliance with account management requirements {{ insert: param, ac-2_prm_10 }};" + }, + { + "id": "ac-2_smt.k", + "name": "item", + "props": [ + { + "name": "label", + "value": "k." + } + ], + "prose": "Establish and implement a process for changing shared or group account authenticators (if deployed) when individuals are removed from the group; and" + }, + { + "id": "ac-2_smt.l", + "name": "item", + "props": [ + { + "name": "label", + "value": "l." + } + ], + "prose": "Align account management processes with personnel termination and transfer processes." + } + ] + }, + { + "id": "ac-2_gdn", + "name": "guidance", + "prose": "Examples of system account types include individual, shared, group, system, guest, anonymous, emergency, developer, temporary, and service. Identification of authorized system users and the specification of access privileges reflect the requirements in other controls in the security plan. Users requiring administrative privileges on system accounts receive additional scrutiny by organizational personnel responsible for approving such accounts and privileged access, including system owner, mission or business owner, senior agency information security officer, or senior agency official for privacy. Types of accounts that organizations may wish to prohibit due to increased risk include shared, group, emergency, anonymous, temporary, and guest accounts.\n\nWhere access involves personally identifiable information, security programs collaborate with the senior agency official for privacy to establish the specific conditions for group and role membership; specify authorized users, group and role membership, and access authorizations for each account; and create, adjust, or remove system accounts in accordance with organizational policies. Policies can include such information as account expiration dates or other factors that trigger the disabling of accounts. Organizations may choose to define access privileges or other attributes by account, type of account, or a combination of the two. Examples of other attributes required for authorizing access include restrictions on time of day, day of week, and point of origin. In defining other system account attributes, organizations consider system-related requirements and mission/business requirements. Failure to consider these factors could affect system availability.\n\nTemporary and emergency accounts are intended for short-term use. Organizations establish temporary accounts as part of normal account activation procedures when there is a need for short-term accounts without the demand for immediacy in account activation. Organizations establish emergency accounts in response to crisis situations and with the need for rapid account activation. Therefore, emergency account activation may bypass normal account authorization processes. Emergency and temporary accounts are not to be confused with infrequently used accounts, including local logon accounts used for special tasks or when network resources are unavailable (may also be known as accounts of last resort). Such accounts remain available and are not subject to automatic disabling or removal dates. Conditions for disabling or deactivating accounts include when shared/group, emergency, or temporary accounts are no longer required and when individuals are transferred or terminated. Changing shared/group authenticators when members leave the group is intended to ensure that former group members do not retain access to the shared or group account. Some types of system accounts may require specialized training." + } + ], + "controls": [ + { + "id": "ac-2.1", + "class": "SP800-53-enhancement", + "title": "Automated System Account Management", + "params": [ + { + "id": "ac-2.1_prm_1", + "label": "organization-defined automated mechanisms" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(1)" + }, + { + "name": "sort-id", + "value": "ac-02.01" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-2.1_smt", + "name": "statement", + "prose": "Support the management of system accounts using {{ insert: param, ac-2.1_prm_1 }}." + }, + { + "id": "ac-2.1_gdn", + "name": "guidance", + "prose": "Automated system account management includes using automated mechanisms to create, enable, modify, disable, and remove accounts; notify account managers when an account is created, enabled, modified, disabled, or removed, or when users are terminated or transferred; monitor system account usage; and report atypical system account usage. Automated mechanisms can include internal system functions and email, telephonic, and text messaging notifications." + } + ] + }, + { + "id": "ac-2.2", + "class": "SP800-53-enhancement", + "title": "Automated Temporary and Emergency Account Management", + "params": [ + { + "id": "ac-2.2_prm_1", + "select": { + "choice": [ + "remove", + "disable" + ] + } + }, + { + "id": "ac-2.2_prm_2", + "label": "organization-defined time period for each type of account" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(2)" + }, + { + "name": "sort-id", + "value": "ac-02.02" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-2.2_smt", + "name": "statement", + "prose": "Automatically {{ insert: param, ac-2.2_prm_1 }} temporary and emergency accounts after {{ insert: param, ac-2.2_prm_2 }}." + }, + { + "id": "ac-2.2_gdn", + "name": "guidance", + "prose": "Management of temporary and emergency accounts includes the removal or disabling of such accounts automatically after a predefined time period rather than at the convenience of the system administrator. Automatic removal or disabling of accounts provides a more consistent implementation." + } + ] + }, + { + "id": "ac-2.3", + "class": "SP800-53-enhancement", + "title": "Disable Accounts", + "params": [ + { + "id": "ac-2.3_prm_1", + "label": "organization-defined time period" + }, + { + "id": "ac-2.3_prm_2", + "label": "organization-defined time period" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(3)" + }, + { + "name": "sort-id", + "value": "ac-02.03" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-2.3_smt", + "name": "statement", + "prose": "Disable accounts within {{ insert: param, ac-2.3_prm_1 }} when the accounts:", + "parts": [ + { + "id": "ac-2.3_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Have expired;" + }, + { + "id": "ac-2.3_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Are no longer associated with a user or individual;" + }, + { + "id": "ac-2.3_smt.c", + "name": "item", + "props": [ + { + "name": "label", + "value": "(c)" + } + ], + "prose": "Are in violation of organizational policy; or" + }, + { + "id": "ac-2.3_smt.d", + "name": "item", + "props": [ + { + "name": "label", + "value": "(d)" + } + ], + "prose": "Have been inactive for {{ insert: param, ac-2.3_prm_2 }}." + } + ] + }, + { + "id": "ac-2.3_gdn", + "name": "guidance", + "prose": "Disabling expired, inactive, or otherwise anomalous accounts supports the concepts of least privilege and least functionality which reduce the attack surface of the system." + } + ] + }, + { + "id": "ac-2.4", + "class": "SP800-53-enhancement", + "title": "Automated Audit Actions", + "props": [ + { + "name": "label", + "value": "AC-2(4)" + }, + { + "name": "sort-id", + "value": "ac-02.04" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + }, + { + "href": "#au-2", + "rel": "related" + }, + { + "href": "#au-6", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-2.4_smt", + "name": "statement", + "prose": "Automatically audit account creation, modification, enabling, disabling, and removal actions." + }, + { + "id": "ac-2.4_gdn", + "name": "guidance", + "prose": "Account management audit records are defined in accordance with [AU-2](#au-2) and reviewed, analyzed, and reported in accordance with [AU-6](#au-6)." + } + ] + }, + { + "id": "ac-2.5", + "class": "SP800-53-enhancement", + "title": "Inactivity Logout", + "params": [ + { + "id": "ac-2.5_prm_1", + "label": "organization-defined time period of expected inactivity or description of when to log out" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(5)" + }, + { + "name": "sort-id", + "value": "ac-02.05" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + }, + { + "href": "#ac-11", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-2.5_smt", + "name": "statement", + "prose": "Require that users log out when {{ insert: param, ac-2.5_prm_1 }}." + }, + { + "id": "ac-2.5_gdn", + "name": "guidance", + "prose": "Inactivity logout is behavior- or policy-based and requires users to take physical action to log out when they are expecting inactivity longer than the defined period. Automatic enforcement of inactivity logout is addressed by [AC-11](#ac-11)." + } + ] + }, + { + "id": "ac-2.6", + "class": "SP800-53-enhancement", + "title": "Dynamic Privilege Management", + "params": [ + { + "id": "ac-2.6_prm_1", + "label": "organization-defined dynamic privilege management capabilities" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(6)" + }, + { + "name": "sort-id", + "value": "ac-02.06" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + }, + { + "href": "#ac-16", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-2.6_smt", + "name": "statement", + "prose": "Implement {{ insert: param, ac-2.6_prm_1 }}." + }, + { + "id": "ac-2.6_gdn", + "name": "guidance", + "prose": "In contrast to access control approaches that employ static accounts and predefined user privileges, dynamic access control approaches rely on runtime access control decisions facilitated by dynamic privilege management, such as attribute-based access control. While user identities remain relatively constant over time, user privileges typically change more frequently based on ongoing mission or business requirements and the operational needs of organizations. An example of dynamic privilege management is the immediate revocation of privileges from users as opposed to requiring that users terminate and restart their sessions to reflect changes in privileges. Dynamic privilege management can also include mechanisms that change user privileges based on dynamic rules as opposed to editing specific user profiles. Examples include automatic adjustments of user privileges if they are operating out of their normal work times, if their job function or assignment changes, or if systems are under duress or in emergency situations. Dynamic privilege management includes the effects of privilege changes, for example, when there are changes to encryption keys used for communications." + } + ] + }, + { + "id": "ac-2.7", + "class": "SP800-53-enhancement", + "title": "Privileged User Accounts", + "params": [ + { + "id": "ac-2.7_prm_1", + "select": { + "choice": [ + "a role-based access scheme", + "an attribute-based access scheme" + ] + } + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(7)" + }, + { + "name": "sort-id", + "value": "ac-02.07" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-2.7_smt", + "name": "statement", + "parts": [ + { + "id": "ac-2.7_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Establish and administer privileged user accounts in accordance with {{ insert: param, ac-2.7_prm_1 }};" + }, + { + "id": "ac-2.7_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Monitor privileged role or attribute assignments;" + }, + { + "id": "ac-2.7_smt.c", + "name": "item", + "props": [ + { + "name": "label", + "value": "(c)" + } + ], + "prose": "Monitor changes to roles or attributes; and" + }, + { + "id": "ac-2.7_smt.d", + "name": "item", + "props": [ + { + "name": "label", + "value": "(d)" + } + ], + "prose": "Revoke access when privileged role or attribute assignments are no longer appropriate." + } + ] + }, + { + "id": "ac-2.7_gdn", + "name": "guidance", + "prose": "Privileged roles are organization-defined roles assigned to individuals that allow those individuals to perform certain security-relevant functions that ordinary users are not authorized to perform. Privileged roles include key management, account management, database administration, system and network administration, and web administration. A role-based access scheme organizes permitted system access and privileges into roles. In contrast, an attribute-based access scheme specifies allowed system access and privileges based on attributes." + } + ] + }, + { + "id": "ac-2.8", + "class": "SP800-53-enhancement", + "title": "Dynamic Account Management", + "params": [ + { + "id": "ac-2.8_prm_1", + "label": "organization-defined system accounts" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(8)" + }, + { + "name": "sort-id", + "value": "ac-02.08" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + }, + { + "href": "#ac-16", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-2.8_smt", + "name": "statement", + "prose": "Create, activate, manage, and deactivate {{ insert: param, ac-2.8_prm_1 }} dynamically." + }, + { + "id": "ac-2.8_gdn", + "name": "guidance", + "prose": "Approaches for dynamically creating, activating, managing, and deactivating system accounts rely on automatically provisioning the accounts at runtime for entities that were previously unknown. Organizations plan for the dynamic management, creation, activation, and deactivation of system accounts by establishing trust relationships, business rules, and mechanisms with appropriate authorities to validate related authorizations and privileges." + } + ] + }, + { + "id": "ac-2.9", + "class": "SP800-53-enhancement", + "title": "Restrictions on Use of Shared and Group Accounts", + "params": [ + { + "id": "ac-2.9_prm_1", + "label": "organization-defined conditions for establishing shared and group accounts" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(9)" + }, + { + "name": "sort-id", + "value": "ac-02.09" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-2.9_smt", + "name": "statement", + "prose": "Only permit the use of shared and group accounts that meet {{ insert: param, ac-2.9_prm_1 }}." + }, + { + "id": "ac-2.9_gdn", + "name": "guidance", + "prose": "Before permitting the use of shared or group accounts, organizations consider the increased risk due to the lack of accountability with such accounts." + } + ] + }, + { + "id": "ac-2.10", + "class": "SP800-53-enhancement", + "title": "Shared and Group Account Credential Change", + "props": [ + { + "name": "label", + "value": "AC-2(10)" + }, + { + "name": "sort-id", + "value": "ac-02.10" + }, + { + "name": "status", + "value": "withdrawn" + } + ], + "links": [ + { + "href": "#ac-2_smt.k", + "rel": "incorporated-into" + } + ] + }, + { + "id": "ac-2.11", + "class": "SP800-53-enhancement", + "title": "Usage Conditions", + "params": [ + { + "id": "ac-2.11_prm_1", + "label": "organization-defined circumstances and/or usage conditions" + }, + { + "id": "ac-2.11_prm_2", + "label": "organization-defined system accounts" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(11)" + }, + { + "name": "sort-id", + "value": "ac-02.11" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-2.11_smt", + "name": "statement", + "prose": "Enforce {{ insert: param, ac-2.11_prm_1 }} for {{ insert: param, ac-2.11_prm_2 }}." + }, + { + "id": "ac-2.11_gdn", + "name": "guidance", + "prose": "Specifying and enforcing usage conditions helps to enforce the principle of least privilege, increase user accountability, and enable effective account monitoring. Account monitoring includes alerts generated if the account is used in violation of organizational parameters. Organizations can describe specific conditions or circumstances under which system accounts can be used, such as by restricting usage to certain days of the week, time of day, or specific durations of time." + } + ] + }, + { + "id": "ac-2.12", + "class": "SP800-53-enhancement", + "title": "Account Monitoring for Atypical Usage", + "params": [ + { + "id": "ac-2.12_prm_1", + "label": "organization-defined atypical usage" + }, + { + "id": "ac-2.12_prm_2", + "label": "organization-defined personnel or roles" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(12)" + }, + { + "name": "sort-id", + "value": "ac-02.12" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + }, + { + "href": "#au-6", + "rel": "related" + }, + { + "href": "#au-7", + "rel": "related" + }, + { + "href": "#ca-7", + "rel": "related" + }, + { + "href": "#ir-8", + "rel": "related" + }, + { + "href": "#si-4", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-2.12_smt", + "name": "statement", + "parts": [ + { + "id": "ac-2.12_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Monitor system accounts for {{ insert: param, ac-2.12_prm_1 }}; and" + }, + { + "id": "ac-2.12_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Report atypical usage of system accounts to {{ insert: param, ac-2.12_prm_2 }}." + } + ] + }, + { + "id": "ac-2.12_gdn", + "name": "guidance", + "prose": "Atypical usage includes accessing systems at certain times of the day or from locations that are not consistent with the normal usage patterns of individuals. Monitoring for atypical usage may reveal rogue behavior by individuals or an attack in progress. Account monitoring may inadvertently create privacy risks since data collected to identify atypical usage may reveal previously unknown information about the behavior of individuals. Organizations assess and document privacy risks from monitoring accounts for atypical usage in their privacy impact assessment and make determinations that are in alignment with their privacy program plan." + } + ] + }, + { + "id": "ac-2.13", + "class": "SP800-53-enhancement", + "title": "Disable Accounts for High-risk Individuals", + "params": [ + { + "id": "ac-2.13_prm_1", + "label": "organization-defined time period" + }, + { + "id": "ac-2.13_prm_2", + "label": "organization-defined significant risks" + } + ], + "props": [ + { + "name": "label", + "value": "AC-2(13)" + }, + { + "name": "sort-id", + "value": "ac-02.13" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "required" + }, + { + "href": "#au-6", + "rel": "related" + }, + { + "href": "#si-4", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-2.13_smt", + "name": "statement", + "prose": "Disable accounts of individuals within {{ insert: param, ac-2.13_prm_1 }} of discovery of {{ insert: param, ac-2.13_prm_2 }}." + }, + { + "id": "ac-2.13_gdn", + "name": "guidance", + "prose": "Users who pose a significant security and/or privacy risk include individuals for whom reliable evidence indicates either the intention to use authorized access to systems to cause harm or through whom adversaries will cause harm. Such harm includes adverse impacts to organizational operations, organizational assets, individuals, other organizations, or the Nation. Close coordination among system administrators, legal staff, human resource managers, and authorizing officials is essential when disabling system accounts for high-risk individuals." + } + ] + } + ] + }, + { + "id": "ac-3", + "class": "SP800-53", + "title": "Access Enforcement", + "props": [ + { + "name": "label", + "value": "AC-3" + }, + { + "name": "sort-id", + "value": "ac-03" + } + ], + "links": [ + { + "href": "#18e71fec-c6fd-475a-925a-5d8495cf8455", + "rel": "reference" + }, + { + "href": "#27847491-5ce1-4f6a-a1e4-9e483782f0ef", + "rel": "reference" + }, + { + "href": "#110e26af-4765-49e1-8740-6750f83fcda1", + "rel": "reference" + }, + { + "href": "#e7942589-e267-4a5a-a3d9-f39a7aae81f0", + "rel": "reference" + }, + { + "href": "#8306620b-1920-4d73-8b21-12008528595f", + "rel": "reference" + }, + { + "href": "#2956e175-f674-43f4-b1b9-e074ad9fc39c", + "rel": "reference" + }, + { + "href": "#388a3aa2-5d85-4bad-b8a3-77db80d63c4f", + "rel": "reference" + }, + { + "href": "#7f473f21-fdbf-4a6c-81a1-0ab95919609d", + "rel": "reference" + }, + { + "href": "#ac-2", + "rel": "related" + }, + { + "href": "#ac-4", + "rel": "related" + }, + { + "href": "#ac-5", + "rel": "related" + }, + { + "href": "#ac-6", + "rel": "related" + }, + { + "href": "#ac-16", + "rel": "related" + }, + { + "href": "#ac-17", + "rel": "related" + }, + { + "href": "#ac-18", + "rel": "related" + }, + { + "href": "#ac-19", + "rel": "related" + }, + { + "href": "#ac-20", + "rel": "related" + }, + { + "href": "#ac-21", + "rel": "related" + }, + { + "href": "#ac-22", + "rel": "related" + }, + { + "href": "#ac-24", + "rel": "related" + }, + { + "href": "#ac-25", + "rel": "related" + }, + { + "href": "#at-2", + "rel": "related" + }, + { + "href": "#at-3", + "rel": "related" + }, + { + "href": "#au-9", + "rel": "related" + }, + { + "href": "#ca-9", + "rel": "related" + }, + { + "href": "#cm-5", + "rel": "related" + }, + { + "href": "#cm-11", + "rel": "related" + }, + { + "href": "#ia-2", + "rel": "related" + }, + { + "href": "#ia-5", + "rel": "related" + }, + { + "href": "#ia-6", + "rel": "related" + }, + { + "href": "#ia-7", + "rel": "related" + }, + { + "href": "#ia-11", + "rel": "related" + }, + { + "href": "#ma-3", + "rel": "related" + }, + { + "href": "#ma-4", + "rel": "related" + }, + { + "href": "#ma-5", + "rel": "related" + }, + { + "href": "#mp-4", + "rel": "related" + }, + { + "href": "#pm-2", + "rel": "related" + }, + { + "href": "#ps-3", + "rel": "related" + }, + { + "href": "#pt-2", + "rel": "related" + }, + { + "href": "#pt-3", + "rel": "related" + }, + { + "href": "#sa-17", + "rel": "related" + }, + { + "href": "#sc-2", + "rel": "related" + }, + { + "href": "#sc-3", + "rel": "related" + }, + { + "href": "#sc-4", + "rel": "related" + }, + { + "href": "#sc-12", + "rel": "related" + }, + { + "href": "#sc-13", + "rel": "related" + }, + { + "href": "#sc-28", + "rel": "related" + }, + { + "href": "#sc-31", + "rel": "related" + }, + { + "href": "#sc-34", + "rel": "related" + }, + { + "href": "#si-4", + "rel": "related" + }, + { + "href": "#si-8", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-3_smt", + "name": "statement", + "prose": "Enforce approved authorizations for logical access to information and system resources in accordance with applicable access control policies." + }, + { + "id": "ac-3_gdn", + "name": "guidance", + "prose": "Access control policies control access between active entities or subjects (i.e., users or processes acting on behalf of users) and passive entities or objects (i.e., devices, files, records, domains) in organizational systems. In addition to enforcing authorized access at the system level and recognizing that systems can host many applications and services in support of mission and business functions, access enforcement mechanisms can also be employed at the application and service level to provide increased information security and privacy. In contrast to logical access controls that are implemented within the system, physical access controls are addressed by the controls in the Physical and Environmental Protection ([PE](#pe)) family." + } + ], + "controls": [ + { + "id": "ac-3.1", + "class": "SP800-53-enhancement", + "title": "Restricted Access to Privileged Functions", + "props": [ + { + "name": "label", + "value": "AC-3(1)" + }, + { + "name": "sort-id", + "value": "ac-03.01" + }, + { + "name": "status", + "value": "withdrawn" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "incorporated-into" + } + ] + }, + { + "id": "ac-3.2", + "class": "SP800-53-enhancement", + "title": "Dual Authorization", + "params": [ + { + "id": "ac-3.2_prm_1", + "label": "organization-defined privileged commands and/or other organization-defined actions" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(2)" + }, + { + "name": "sort-id", + "value": "ac-03.02" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + }, + { + "href": "#cp-9", + "rel": "related" + }, + { + "href": "#mp-6", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-3.2_smt", + "name": "statement", + "prose": "Enforce dual authorization for {{ insert: param, ac-3.2_prm_1 }}." + }, + { + "id": "ac-3.2_gdn", + "name": "guidance", + "prose": "Dual authorization, also known as two-person control, reduces risk related to insider threats. Dual authorization mechanisms require the approval of two authorized individuals to execute. To reduce the risk of collusion, organizations consider rotating dual authorization duties. Organizations consider the risk associated with implementing dual authorization mechanisms when immediate responses are necessary to ensure public and environmental safety." + } + ] + }, + { + "id": "ac-3.3", + "class": "SP800-53-enhancement", + "title": "Mandatory Access Control", + "params": [ + { + "id": "ac-3.3_prm_1", + "label": "organization-defined mandatory access control policy" + }, + { + "id": "ac-3.3_prm_2", + "label": "organization-defined subjects" + }, + { + "id": "ac-3.3_prm_3", + "label": "organization-defined privileges" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(3)" + }, + { + "name": "sort-id", + "value": "ac-03.03" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + }, + { + "href": "#sc-7", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-3.3_smt", + "name": "statement", + "prose": "Enforce {{ insert: param, ac-3.3_prm_1 }} over the set of covered subjects and objects specified in the policy, and where the policy:", + "parts": [ + { + "id": "ac-3.3_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Is uniformly enforced across the covered subjects and objects within the system;" + }, + { + "id": "ac-3.3_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Specifies that a subject that has been granted access to information is constrained from doing any of the following;", + "parts": [ + { + "id": "ac-3.3_smt.b.1", + "name": "item", + "props": [ + { + "name": "label", + "value": "(1)" + } + ], + "prose": "Passing the information to unauthorized subjects or objects;" + }, + { + "id": "ac-3.3_smt.b.2", + "name": "item", + "props": [ + { + "name": "label", + "value": "(2)" + } + ], + "prose": "Granting its privileges to other subjects;" + }, + { + "id": "ac-3.3_smt.b.3", + "name": "item", + "props": [ + { + "name": "label", + "value": "(3)" + } + ], + "prose": "Changing one or more security attributes (specified by the policy) on subjects, objects, the system, or system components;" + }, + { + "id": "ac-3.3_smt.b.4", + "name": "item", + "props": [ + { + "name": "label", + "value": "(4)" + } + ], + "prose": "Choosing the security attributes and attribute values (specified by the policy) to be associated with newly created or modified objects; and" + }, + { + "id": "ac-3.3_smt.b.5", + "name": "item", + "props": [ + { + "name": "label", + "value": "(5)" + } + ], + "prose": "Changing the rules governing access control; and" + } + ] + }, + { + "id": "ac-3.3_smt.c", + "name": "item", + "props": [ + { + "name": "label", + "value": "(c)" + } + ], + "prose": "Specifies that {{ insert: param, ac-3.3_prm_2 }} may explicitly be granted {{ insert: param, ac-3.3_prm_3 }} such that they are not limited by any defined subset (or all) of the above constraints." + } + ] + }, + { + "id": "ac-3.3_gdn", + "name": "guidance", + "prose": "Mandatory access control is a type of nondiscretionary access control. Mandatory access control policies constrain what actions subjects can take with information obtained from objects for which they have already been granted access. This prevents the subjects from passing the information to unauthorized subjects and objects. Mandatory access control policies constrain actions that subjects can take with respect to the propagation of access control privileges; that is, a subject with a privilege cannot pass that privilege to other subjects. The policy is uniformly enforced over all subjects and objects to which the system has control. Otherwise, the access control policy can be circumvented. This enforcement is provided by an implementation that meets the reference monitor concept as described in [AC-25](#ac-25). The policy is bounded by the system (i.e., once the information is passed outside of the control of the system, additional means may be required to ensure that the constraints on the information remain in effect).\n\nThe trusted subjects described above are granted privileges consistent with the concept of least privilege (see [AC-6](#ac-6)). Trusted subjects are only given the minimum privileges necessary for satisfying organizational mission/business needs relative to the above policy. The control is most applicable when there is a mandate that establishes a policy regarding access to controlled unclassified information or classified information and some users of the system are not authorized access to all such information resident in the system. Mandatory access control can operate in conjunction with discretionary access control as described in [AC-3(4)](#ac-3.4). A subject constrained in its operation by mandatory access control policies can still operate under the less rigorous constraints of AC-3(4), but mandatory access control policies take precedence over the less rigorous constraints of AC-3(4). For example, while a mandatory access control policy imposes a constraint that prevents a subject from passing information to another subject operating at a different impact or classification level, AC-3(4) permits the subject to pass the information to any other subject with the same impact or classification level as the subject. Examples of mandatory access control policies include the Bell-LaPadula policy to protect confidentiality of information and the Biba policy to protect the integrity of information." + } + ] + }, + { + "id": "ac-3.4", + "class": "SP800-53-enhancement", + "title": "Discretionary Access Control", + "params": [ + { + "id": "ac-3.4_prm_1", + "label": "organization-defined discretionary access control policy" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(4)" + }, + { + "name": "sort-id", + "value": "ac-03.04" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-3.4_smt", + "name": "statement", + "prose": "Enforce {{ insert: param, ac-3.4_prm_1 }} over the set of covered subjects and objects specified in the policy, and where the policy specifies that a subject that has been granted access to information can do one or more of the following:", + "parts": [ + { + "id": "ac-3.4_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Pass the information to any other subjects or objects;" + }, + { + "id": "ac-3.4_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Grant its privileges to other subjects;" + }, + { + "id": "ac-3.4_smt.c", + "name": "item", + "props": [ + { + "name": "label", + "value": "(c)" + } + ], + "prose": "Change security attributes on subjects, objects, the system, or the system’s components;" + }, + { + "id": "ac-3.4_smt.d", + "name": "item", + "props": [ + { + "name": "label", + "value": "(d)" + } + ], + "prose": "Choose the security attributes to be associated with newly created or revised objects; or" + }, + { + "id": "ac-3.4_smt.e", + "name": "item", + "props": [ + { + "name": "label", + "value": "(e)" + } + ], + "prose": "Change the rules governing access control." + } + ] + }, + { + "id": "ac-3.4_gdn", + "name": "guidance", + "prose": "When discretionary access control policies are implemented, subjects are not constrained with regard to what actions they can take with information for which they have already been granted access. Thus, subjects that have been granted access to information are not prevented from passing the information to other subjects or objects (i.e., subjects have the discretion to pass). Discretionary access control can operate in conjunction with mandatory access control as described in [AC-3(3)](#ac-3.3) and [AC-3(15)](#ac-3.15). A subject that is constrained in its operation by mandatory access control policies can still operate under the less rigorous constraints of discretionary access control. Therefore, while [AC-3(3)](#ac-3.3) imposes constraints that prevent a subject from passing information to another subject operating at a different impact or classification level, [AC-3(4)](#ac-3.4) permits the subject to pass the information to any subject at the same impact or classification level. The policy is bounded by the system. Once the information is passed outside of system control, additional means may be required to ensure that the constraints remain in effect. While traditional definitions of discretionary access control require identity-based access control, that limitation is not required for this particular use of discretionary access control." + } + ] + }, + { + "id": "ac-3.5", + "class": "SP800-53-enhancement", + "title": "Security-relevant Information", + "params": [ + { + "id": "ac-3.5_prm_1", + "label": "organization-defined security-relevant information" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(5)" + }, + { + "name": "sort-id", + "value": "ac-03.05" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + }, + { + "href": "#cm-6", + "rel": "related" + }, + { + "href": "#sc-39", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-3.5_smt", + "name": "statement", + "prose": "Prevent access to {{ insert: param, ac-3.5_prm_1 }} except during secure, non-operable system states." + }, + { + "id": "ac-3.5_gdn", + "name": "guidance", + "prose": "Security-relevant information is information within systems that can potentially impact the operation of security functions or the provision of security services in a manner that could result in failure to enforce system security and privacy policies or maintain the separation of code and data. Security-relevant information includes access control lists, filtering rules for routers or firewalls, configuration parameters for security services, and cryptographic key management information. Secure, non-operable system states include the times in which systems are not performing mission or business-related processing, such as when the system is offline for maintenance, boot-up, troubleshooting, or shut down." + } + ] + }, + { + "id": "ac-3.6", + "class": "SP800-53-enhancement", + "title": "Protection of User and System Information", + "props": [ + { + "name": "label", + "value": "AC-3(6)" + }, + { + "name": "sort-id", + "value": "ac-03.06" + }, + { + "name": "status", + "value": "withdrawn" + } + ], + "links": [ + { + "href": "#mp-4", + "rel": "incorporated-into" + }, + { + "href": "#sc-28", + "rel": "incorporated-into" + } + ] + }, + { + "id": "ac-3.7", + "class": "SP800-53-enhancement", + "title": "Role-based Access Control", + "params": [ + { + "id": "ac-3.7_prm_1", + "label": "organization-defined roles and users authorized to assume such roles" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(7)" + }, + { + "name": "sort-id", + "value": "ac-03.07" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-3.7_smt", + "name": "statement", + "prose": "Enforce a role-based access control policy over defined subjects and objects and control access based upon {{ insert: param, ac-3.7_prm_1 }}." + }, + { + "id": "ac-3.7_gdn", + "name": "guidance", + "prose": "Role-based access control (RBAC) is an access control policy that enforces access to objects and system functions based on the defined role (i.e., job function) of the subject. Organizations can create specific roles based on job functions and the authorizations (i.e., privileges) to perform needed operations on the systems associated with the organization-defined roles. When users are assigned to specific roles, they inherit the authorizations or privileges defined for those roles. RBAC simplifies privilege administration for organizations because privileges are not assigned directly to every user (which can be a large number of individuals) but are instead acquired through role assignments. RBAC can also increase privacy and security risk if individuals assigned to a role are given access to information beyond what they need to support organizational missions or business functions. RBAC can be implemented as a mandatory or discretionary form of access control. For organizations implementing RBAC with mandatory access controls, the requirements in [AC-3(3)](#ac-3.3) define the scope of the subjects and objects covered by the policy." + } + ] + }, + { + "id": "ac-3.8", + "class": "SP800-53-enhancement", + "title": "Revocation of Access Authorizations", + "params": [ + { + "id": "ac-3.8_prm_1", + "label": "organization-defined rules governing the timing of revocations of access authorizations" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(8)" + }, + { + "name": "sort-id", + "value": "ac-03.08" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-3.8_smt", + "name": "statement", + "prose": "Enforce the revocation of access authorizations resulting from changes to the security attributes of subjects and objects based on {{ insert: param, ac-3.8_prm_1 }}." + }, + { + "id": "ac-3.8_gdn", + "name": "guidance", + "prose": "Revocation of access rules may differ based on the types of access revoked. For example, if a subject (i.e., user or process acting on behalf of a user) is removed from a group, access may not be revoked until the next time the object is opened or the next time the subject attempts to access the object. Revocation based on changes to security labels may take effect immediately. Organizations provide alternative approaches on how to make revocations immediate if systems cannot provide such capability and immediate revocation is necessary." + } + ] + }, + { + "id": "ac-3.9", + "class": "SP800-53-enhancement", + "title": "Controlled Release", + "params": [ + { + "id": "ac-3.9_prm_1", + "label": "organization-defined system or system component" + }, + { + "id": "ac-3.9_prm_2", + "label": "organization-defined controls" + }, + { + "id": "ac-3.9_prm_3", + "label": "organization-defined controls" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(9)" + }, + { + "name": "sort-id", + "value": "ac-03.09" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + }, + { + "href": "#ca-3", + "rel": "related" + }, + { + "href": "#pt-7", + "rel": "related" + }, + { + "href": "#pt-8", + "rel": "related" + }, + { + "href": "#sa-9", + "rel": "related" + }, + { + "href": "#sc-16", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-3.9_smt", + "name": "statement", + "prose": "Release information outside of the system only if:", + "parts": [ + { + "id": "ac-3.9_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "The receiving {{ insert: param, ac-3.9_prm_1 }} provides {{ insert: param, ac-3.9_prm_2 }}; and" + }, + { + "id": "ac-3.9_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": " {{ insert: param, ac-3.9_prm_3 }} are used to validate the appropriateness of the information designated for release." + } + ] + }, + { + "id": "ac-3.9_gdn", + "name": "guidance", + "prose": "Organizations can only directly protect information when it resides within the system. Additional controls may be needed to ensure that organizational information is adequately protected once it is transmitted outside of the system. In situations where the system is unable to determine the adequacy of the protections provided by external entities, as a mitigation measure, organizations procedurally determine whether the external systems are providing adequate controls. The means used to determine the adequacy of controls provided by external systems include conducting periodic assessments (inspections/tests), establishing agreements between the organization and its counterpart organizations, or some other process. The means used by external entities to protect the information received need not be the same as those used by the organization, but the means employed are sufficient to provide consistent adjudication of the security and privacy policy to protect the information and individuals’ privacy.\n\nControlled release of information requires systems to implement technical or procedural means to validate the information prior to releasing it to external systems. For example, if the system passes information to a system controlled by another organization, technical means are employed to validate that the security and privacy attributes associated with the exported information are appropriate for the receiving system. Alternatively, if the system passes information to a printer in organization-controlled space, procedural means can be employed to ensure that only authorized individuals gain access to the printer." + } + ] + }, + { + "id": "ac-3.10", + "class": "SP800-53-enhancement", + "title": "Audited Override of Access Control Mechanisms", + "params": [ + { + "id": "ac-3.10_prm_1", + "label": "organization-defined conditions" + }, + { + "id": "ac-3.10_prm_2", + "label": "organization-defined roles" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(10)" + }, + { + "name": "sort-id", + "value": "ac-03.10" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + }, + { + "href": "#au-2", + "rel": "related" + }, + { + "href": "#au-6", + "rel": "related" + }, + { + "href": "#au-10", + "rel": "related" + }, + { + "href": "#au-12", + "rel": "related" + }, + { + "href": "#au-14", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-3.10_smt", + "name": "statement", + "prose": "Employ an audited override of automated access control mechanisms under {{ insert: param, ac-3.10_prm_1 }} by {{ insert: param, ac-3.10_prm_2 }}." + }, + { + "id": "ac-3.10_gdn", + "name": "guidance", + "prose": "In certain situations, such as when there is a threat to human life or an event that threatens the organization’s ability to carry out critical missions or business functions, an override capability for access control mechanisms may be needed. Override conditions are defined by organizations and used only in those limited circumstances. Audit events are defined in [AU-2](#au-2). Audit records are generated in [AU-12](#au-12)." + } + ] + }, + { + "id": "ac-3.11", + "class": "SP800-53-enhancement", + "title": "Restrict Access to Specific Information Types", + "params": [ + { + "id": "ac-3.11_prm_1", + "label": "organization-defined information types" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(11)" + }, + { + "name": "sort-id", + "value": "ac-03.11" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + }, + { + "href": "#cm-8", + "rel": "related" + }, + { + "href": "#cm-12", + "rel": "related" + }, + { + "href": "#cm-13", + "rel": "related" + }, + { + "href": "#pm-5", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-3.11_smt", + "name": "statement", + "prose": "Restrict access to data repositories containing {{ insert: param, ac-3.11_prm_1 }}." + }, + { + "id": "ac-3.11_gdn", + "name": "guidance", + "prose": "Restricting access to specific information is intended to provide flexibility regarding access control of specific information types within a system. For example, role-based access could be employed to allow access to only a specific type of personally identifiable information within a database rather than allowing access to the database in its entirety. Other examples include restricting access to cryptographic keys, authentication information, and selected system information." + } + ] + }, + { + "id": "ac-3.12", + "class": "SP800-53-enhancement", + "title": "Assert and Enforce Application Access", + "params": [ + { + "id": "ac-3.12_prm_1", + "label": "organization-defined system applications and functions" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(12)" + }, + { + "name": "sort-id", + "value": "ac-03.12" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + }, + { + "href": "#cm-7", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-3.12_smt", + "name": "statement", + "parts": [ + { + "id": "ac-3.12_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Require applications to assert, as part of the installation process, the access needed to the following system applications and functions: {{ insert: param, ac-3.12_prm_1 }};" + }, + { + "id": "ac-3.12_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Provide an enforcement mechanism to prevent unauthorized access; and" + }, + { + "id": "ac-3.12_smt.c", + "name": "item", + "props": [ + { + "name": "label", + "value": "(c)" + } + ], + "prose": "Approve access changes after initial installation of the application." + } + ] + }, + { + "id": "ac-3.12_gdn", + "name": "guidance", + "prose": "Asserting and enforcing application access is intended to address applications that need to access existing system applications and functions, including user contacts, global positioning systems, cameras, keyboards, microphones, networks, phones, or other files." + } + ] + }, + { + "id": "ac-3.13", + "class": "SP800-53-enhancement", + "title": "Attribute-based Access Control", + "params": [ + { + "id": "ac-3.13_prm_1", + "label": "organization-defined attributes to assume access permissions" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(13)" + }, + { + "name": "sort-id", + "value": "ac-03.13" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-3.13_smt", + "name": "statement", + "prose": "Enforce attribute-based access control policy over defined subjects and objects and control access based upon {{ insert: param, ac-3.13_prm_1 }}." + }, + { + "id": "ac-3.13_gdn", + "name": "guidance", + "prose": "Attribute-based access control is an access control policy that restricts system access to authorized users based on specified organizational attributes (e.g., job function, identity), action attributes (e.g., read, write, delete), environmental attributes (e.g., time of day, location), and resource attributes (e.g., classification of a document). Organizations can create rules based on attributes and the authorizations (i.e., privileges) to perform needed operations on the systems associated with organization-defined attributes and rules. When users are assigned to attributes defined in attribute-based access control policies or rules, they can be provisioned to a system with the appropriate privileges or dynamically granted access to a protected resource. Attribute-based access control can be implemented as either a mandatory or discretionary form of access control. When implemented with mandatory access controls, the requirements in [AC-3(3)](#ac-3.3) define the scope of the subjects and objects covered by the policy." + } + ] + }, + { + "id": "ac-3.14", + "class": "SP800-53-enhancement", + "title": "Individual Access", + "params": [ + { + "id": "ac-3.14_prm_1", + "label": "organization-defined mechanisms" + }, + { + "id": "ac-3.14_prm_2", + "label": "organization-defined elements" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(14)" + }, + { + "name": "sort-id", + "value": "ac-03.14" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + }, + { + "href": "#ia-8", + "rel": "related" + }, + { + "href": "#pm-22", + "rel": "related" + }, + { + "href": "#pm-20", + "rel": "related" + }, + { + "href": "#pm-21", + "rel": "related" + }, + { + "href": "#pt-6", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-3.14_smt", + "name": "statement", + "prose": "Provide {{ insert: param, ac-3.14_prm_1 }} to enable individuals to have access to the following elements of their personally identifiable information: {{ insert: param, ac-3.14_prm_2 }}." + }, + { + "id": "ac-3.14_gdn", + "name": "guidance", + "prose": "Individual access affords individuals the ability to review personally identifiable information about them held within organizational records, regardless of format. Access helps individuals to develop an understanding about how their personally identifiable information is being processed. It can also help individuals ensure that their data is accurate. Access mechanisms can include request forms and application interfaces. For federal agencies, [PRIVACT](#18e71fec-c6fd-475a-925a-5d8495cf8455) processes can be located in systems of record notices and on agency websites. Access to certain types of records may not be appropriate (e.g., for federal agencies, law enforcement records within a system of records may be exempt from disclosure under the [PRIVACT](#18e71fec-c6fd-475a-925a-5d8495cf8455)) or may require certain levels of authentication assurance. Organizational personnel consult with the senior agency official for privacy and legal counsel to determine appropriate mechanisms and access rights or limitations." + } + ] + }, + { + "id": "ac-3.15", + "class": "SP800-53-enhancement", + "title": "Discretionary and Mandatory Access Control", + "params": [ + { + "id": "ac-3.15_prm_1", + "label": "organization-defined mandatory access control policy" + }, + { + "id": "ac-3.15_prm_2", + "label": "organization-defined discretionary access control policy" + } + ], + "props": [ + { + "name": "label", + "value": "AC-3(15)" + }, + { + "name": "sort-id", + "value": "ac-03.15" + } + ], + "links": [ + { + "href": "#ac-3", + "rel": "required" + }, + { + "href": "#sc-2", + "rel": "related" + }, + { + "href": "#sc-3", + "rel": "related" + }, + { + "href": "#ac-4", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-3.15_smt", + "name": "statement", + "parts": [ + { + "id": "ac-3.15_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Enforce {{ insert: param, ac-3.15_prm_1 }} over the set of covered subjects and objects specified in the policy; and" + }, + { + "id": "ac-3.15_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Enforce {{ insert: param, ac-3.15_prm_2 }} over the set of covered subjects and objects specified in the policy." + } + ] + }, + { + "id": "ac-3.15_gdn", + "name": "guidance", + "prose": "Simultaneously implementing a mandatory access control policy and a discretionary access control policy can provide additional protection against the unauthorized execution of code by users or processes acting on behalf of users. This helps prevent a single compromised user or process from compromising the entire system." + } + ] + } + ] + }, + { + "id": "ac-4", + "class": "SP800-53", + "title": "Information Flow Enforcement", + "params": [ + { + "id": "ac-4_prm_1", + "label": "organization-defined information flow control policies" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4" + }, + { + "name": "sort-id", + "value": "ac-04" + } + ], + "links": [ + { + "href": "#e3cc0520-a366-4fc9-abc2-5272db7e3564", + "rel": "reference" + }, + { + "href": "#2956e175-f674-43f4-b1b9-e074ad9fc39c", + "rel": "reference" + }, + { + "href": "#388a3aa2-5d85-4bad-b8a3-77db80d63c4f", + "rel": "reference" + }, + { + "href": "#a2590922-82f3-4277-83c0-ca5bee06dba4", + "rel": "reference" + }, + { + "href": "#ac-3", + "rel": "related" + }, + { + "href": "#ac-6", + "rel": "related" + }, + { + "href": "#ac-16", + "rel": "related" + }, + { + "href": "#ac-17", + "rel": "related" + }, + { + "href": "#ac-19", + "rel": "related" + }, + { + "href": "#ac-21", + "rel": "related" + }, + { + "href": "#au-10", + "rel": "related" + }, + { + "href": "#ca-3", + "rel": "related" + }, + { + "href": "#ca-9", + "rel": "related" + }, + { + "href": "#cm-7", + "rel": "related" + }, + { + "href": "#pl-9", + "rel": "related" + }, + { + "href": "#pm-24", + "rel": "related" + }, + { + "href": "#sa-17", + "rel": "related" + }, + { + "href": "#sc-4", + "rel": "related" + }, + { + "href": "#sc-7", + "rel": "related" + }, + { + "href": "#sc-16", + "rel": "related" + }, + { + "href": "#sc-31", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-4_smt", + "name": "statement", + "prose": "Enforce approved authorizations for controlling the flow of information within the system and between connected systems based on {{ insert: param, ac-4_prm_1 }}." + }, + { + "id": "ac-4_gdn", + "name": "guidance", + "prose": "Information flow control regulates where information can travel within a system and between systems (in contrast to who is allowed to access the information) and without regard to subsequent accesses to that information. Flow control restrictions include blocking external traffic that claims to be from within the organization, keeping export-controlled information from being transmitted in the clear to the Internet, restricting web requests that are not from the internal web proxy server, and limiting information transfers between organizations based on data structures and content. Transferring information between organizations may require an agreement specifying how the information flow is enforced (see [CA-3](#ca-3)). Transferring information between systems in different security or privacy domains with different security or privacy policies introduces the risk that such transfers violate one or more domain security or privacy policies. In such situations, information owners/stewards provide guidance at designated policy enforcement points between connected systems. Organizations consider mandating specific architectural solutions to enforce specific security and privacy policies. Enforcement includes prohibiting information transfers between connected systems (i.e., allowing access only), verifying write permissions before accepting information from another security or privacy domain or connected system, employing hardware mechanisms to enforce one-way information flows, and implementing trustworthy regrading mechanisms to reassign security or privacy attributes and labels.\n\nOrganizations commonly employ information flow control policies and enforcement mechanisms to control the flow of information between designated sources and destinations within systems and between connected systems. Flow control is based on the characteristics of the information and/or the information path. Enforcement occurs, for example, in boundary protection devices that employ rule sets or establish configuration settings that restrict system services, provide a packet-filtering capability based on header information, or provide a message-filtering capability based on message content. Organizations also consider the trustworthiness of filtering and/or inspection mechanisms (i.e., hardware, firmware, and software components) that are critical to information flow enforcement. Control enhancements 3 through 32 primarily address cross-domain solution needs that focus on more advanced filtering techniques, in-depth analysis, and stronger flow enforcement mechanisms implemented in cross-domain products, such as high-assurance guards. Such capabilities are generally not available in commercial off-the-shelf products. Information flow enforcement also applies to control plane traffic (e.g., routing and DNS)." + } + ], + "controls": [ + { + "id": "ac-4.1", + "class": "SP800-53-enhancement", + "title": "Object Security and Privacy Attributes", + "params": [ + { + "id": "ac-4.1_prm_1", + "label": "organization-defined security and privacy attributes" + }, + { + "id": "ac-4.1_prm_2", + "label": "organization-defined information, source, and destination objects" + }, + { + "id": "ac-4.1_prm_3", + "label": "organization-defined information flow control policies" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(1)" + }, + { + "name": "sort-id", + "value": "ac-04.01" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.1_smt", + "name": "statement", + "prose": "Use {{ insert: param, ac-4.1_prm_1 }} associated with {{ insert: param, ac-4.1_prm_2 }} to enforce {{ insert: param, ac-4.1_prm_3 }} as a basis for flow control decisions." + }, + { + "id": "ac-4.1_gdn", + "name": "guidance", + "prose": "Information flow enforcement mechanisms compare security and privacy attributes associated with information (i.e., data content and structure) and source and destination objects and respond appropriately when the enforcement mechanisms encounter information flows not explicitly allowed by information flow policies. For example, an information object labeled Secret would be allowed to flow to a destination object labeled Secret, but an information object labeled Top Secret would not be allowed to flow to a destination object labeled Secret. A dataset of personally identifiable information may be tagged with restrictions against combining with other types of datasets and, thus, would not be allowed to flow to the restricted dataset. Security and privacy attributes can also include source and destination addresses employed in traffic filter firewalls. Flow enforcement using explicit security or privacy attributes can be used, for example, to control the release of certain types of information." + } + ] + }, + { + "id": "ac-4.2", + "class": "SP800-53-enhancement", + "title": "Processing Domains", + "params": [ + { + "id": "ac-4.2_prm_1", + "label": "organization-defined information flow control policies" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(2)" + }, + { + "name": "sort-id", + "value": "ac-04.02" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + }, + { + "href": "#sc-39", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-4.2_smt", + "name": "statement", + "prose": "Use protected processing domains to enforce {{ insert: param, ac-4.2_prm_1 }} as a basis for flow control decisions." + }, + { + "id": "ac-4.2_gdn", + "name": "guidance", + "prose": "Protected processing domains within systems are processing spaces that have controlled interactions with other processing spaces, enabling control of information flows between these spaces and to/from information objects. A protected processing domain can be provided, for example, by implementing domain and type enforcement. In domain and type enforcement, system processes are assigned to domains, information is identified by types, and information flows are controlled based on allowed information accesses (i.e., determined by domain and type), allowed signaling among domains, and allowed process transitions to other domains." + } + ] + }, + { + "id": "ac-4.3", + "class": "SP800-53-enhancement", + "title": "Dynamic Information Flow Control", + "params": [ + { + "id": "ac-4.3_prm_1", + "label": "organization-defined information flow control policies" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(3)" + }, + { + "name": "sort-id", + "value": "ac-04.03" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + }, + { + "href": "#si-4", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-4.3_smt", + "name": "statement", + "prose": "Enforce {{ insert: param, ac-4.3_prm_1 }}." + }, + { + "id": "ac-4.3_gdn", + "name": "guidance", + "prose": "Organizational policies regarding dynamic information flow control include allowing or disallowing information flows based on changing conditions or mission or operational considerations. Changing conditions include changes in risk tolerance due to changes in the immediacy of mission or business needs, changes in the threat environment, and detection of potentially harmful or adverse events." + } + ] + }, + { + "id": "ac-4.4", + "class": "SP800-53-enhancement", + "title": "Flow Control of Encrypted Information", + "params": [ + { + "id": "ac-4.4_prm_1", + "label": "organization-defined information flow control mechanisms" + }, + { + "id": "ac-4.4_prm_2", + "select": { + "how-many": "one-or-more", + "choice": [ + "decrypting the information", + "blocking the flow of the encrypted information", + "terminating communications sessions attempting to pass encrypted information", + " {{ insert: param, ac-4.4_prm_3 }} " + ] + } + }, + { + "id": "ac-4.4_prm_3", + "depends-on": "ac-4.4_prm_2", + "label": "organization-defined procedure or method", + "values": ["my procedure"] + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(4)" + }, + { + "name": "sort-id", + "value": "ac-04.04" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + }, + { + "href": "#si-4", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-4.4_smt", + "name": "statement", + "prose": "Prevent encrypted information from bypassing {{ insert: param, ac-4.4_prm_1 }} by {{ insert: param, ac-4.4_prm_2 }}." + }, + { + "id": "ac-4.4_gdn", + "name": "guidance", + "prose": "Flow control mechanisms include content checking, security policy filters, and data type identifiers. The term encryption is extended to cover encoded data not recognized by filtering mechanisms." + } + ] + }, + { + "id": "ac-4.5", + "class": "SP800-53-enhancement", + "title": "Embedded Data Types", + "params": [ + { + "id": "ac-4.5_prm_1", + "label": "organization-defined limitations" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(5)" + }, + { + "name": "sort-id", + "value": "ac-04.05" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.5_smt", + "name": "statement", + "prose": "Enforce {{ insert: param, ac-4.5_prm_1 }} on embedding data types within other data types." + }, + { + "id": "ac-4.5_gdn", + "name": "guidance", + "prose": "Embedding data types within other data types may result in reduced flow control effectiveness. Data type embedding includes inserting files as objects within other files and using compressed or archived data types that may include multiple embedded data types. Limitations on data type embedding consider the levels of embedding and prohibit levels of data type embedding that are beyond the capability of the inspection tools." + } + ] + }, + { + "id": "ac-4.6", + "class": "SP800-53-enhancement", + "title": "Metadata", + "params": [ + { + "id": "ac-4.6_prm_1", + "label": "organization-defined metadata" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(6)" + }, + { + "name": "sort-id", + "value": "ac-04.06" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + }, + { + "href": "#ac-16", + "rel": "related" + }, + { + "href": "#si-7", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-4.6_smt", + "name": "statement", + "prose": "Enforce information flow control based on {{ insert: param, ac-4.6_prm_1 }}." + }, + { + "id": "ac-4.6_gdn", + "name": "guidance", + "prose": "Metadata is information that describes the characteristics of data. Metadata can include structural metadata describing data structures or descriptive metadata describing data content. Enforcement of allowed information flows based on metadata enables simpler and more effective flow control. Organizations consider the trustworthiness of metadata regarding data accuracy (i.e., knowledge that the metadata values are correct with respect to the data), data integrity (i.e., protecting against unauthorized changes to metadata tags), and the binding of metadata to the data payload (i.e., employing sufficiently strong binding techniques with appropriate assurance)." + } + ] + }, + { + "id": "ac-4.7", + "class": "SP800-53-enhancement", + "title": "One-way Flow Mechanisms", + "props": [ + { + "name": "label", + "value": "AC-4(7)" + }, + { + "name": "sort-id", + "value": "ac-04.07" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.7_smt", + "name": "statement", + "prose": "Enforce one-way information flows through hardware-based flow control mechanisms." + }, + { + "id": "ac-4.7_gdn", + "name": "guidance", + "prose": "One-way flow mechanisms may also be referred to as a unidirectional network, unidirectional security gateway, or data diode. One-way flow mechanisms can be used to prevent data from being exported from a higher impact or classified domain or system while permitting data from a lower impact or unclassified domain or system to be imported." + } + ] + }, + { + "id": "ac-4.8", + "class": "SP800-53-enhancement", + "title": "Security and Privacy Policy Filters", + "params": [ + { + "id": "ac-4.8_prm_1", + "label": "organization-defined security or privacy policy filters" + }, + { + "id": "ac-4.8_prm_2", + "label": "organization-defined information flows" + }, + { + "id": "ac-4.8_prm_3", + "select": { + "how-many": "one-or-more", + "choice": [ + "Block", + "Strip", + "Modify", + "Quarantine" + ] + } + }, + { + "id": "ac-4.8_prm_4", + "label": "organization-defined security or privacy policy" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(8)" + }, + { + "name": "sort-id", + "value": "ac-04.08" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.8_smt", + "name": "statement", + "parts": [ + { + "id": "ac-4.8_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Enforce information flow control using {{ insert: param, ac-4.8_prm_1 }} as a basis for flow control decisions for {{ insert: param, ac-4.8_prm_2 }}; and" + }, + { + "id": "ac-4.8_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": " {{ insert: param, ac-4.8_prm_3 }} data after a filter processing failure in accordance with {{ insert: param, ac-4.8_prm_4 }}." + } + ] + }, + { + "id": "ac-4.8_gdn", + "name": "guidance", + "prose": "Organization-defined security or privacy policy filters can address data structures and content. For example, security or privacy policy filters for data structures can check for maximum file lengths, maximum field sizes, and data/file types (for structured and unstructured data). Security or privacy policy filters for data content can check for specific words, enumerated values or data value ranges, and hidden content. Structured data permits the interpretation of data content by applications. Unstructured data refers to digital information without a data structure or with a data structure that does not facilitate the development of rule sets to address the impact or classification level of the information conveyed by the data or the flow enforcement decisions. Unstructured data consists of bitmap objects that are inherently non-language-based (i.e., image, video, or audio files) and textual objects that are based on written or printed languages. Organizations can implement more than one security or privacy policy filter to meet information flow control objectives." + } + ] + }, + { + "id": "ac-4.9", + "class": "SP800-53-enhancement", + "title": "Human Reviews", + "params": [ + { + "id": "ac-4.9_prm_1", + "label": "organization-defined information flows" + }, + { + "id": "ac-4.9_prm_2", + "label": "organization-defined conditions" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(9)" + }, + { + "name": "sort-id", + "value": "ac-04.09" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.9_smt", + "name": "statement", + "prose": "Enforce the use of human reviews for {{ insert: param, ac-4.9_prm_1 }} under the following conditions: {{ insert: param, ac-4.9_prm_2 }}." + }, + { + "id": "ac-4.9_gdn", + "name": "guidance", + "prose": "Organizations define security or privacy policy filters for all situations where automated flow control decisions are possible. When a fully automated flow control decision is not possible, then a human review may be employed in lieu of or as a complement to automated security or privacy policy filtering. Human reviews may also be employed as deemed necessary by organizations." + } + ] + }, + { + "id": "ac-4.10", + "class": "SP800-53-enhancement", + "title": "Enable and Disable Security or Privacy Policy Filters", + "params": [ + { + "id": "ac-4.10_prm_1", + "label": "organization-defined security or privacy policy filters" + }, + { + "id": "ac-4.10_prm_2", + "label": "organization-defined conditions" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(10)" + }, + { + "name": "sort-id", + "value": "ac-04.10" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.10_smt", + "name": "statement", + "prose": "Provide the capability for privileged administrators to enable and disable {{ insert: param, ac-4.10_prm_1 }} under the following conditions: {{ insert: param, ac-4.10_prm_2 }}." + }, + { + "id": "ac-4.10_gdn", + "name": "guidance", + "prose": "For example, as allowed by the system authorization, administrators can enable security or privacy policy filters to accommodate approved data types. Administrators also have the capability to select the filters that are executed on a specific data flow based on the type of data that is being transferred, the source and destination security domains, and other security or privacy relevant features, as needed." + } + ] + }, + { + "id": "ac-4.11", + "class": "SP800-53-enhancement", + "title": "Configuration of Security or Privacy Policy Filters", + "params": [ + { + "id": "ac-4.11_prm_1", + "label": "organization-defined security or privacy policy filters" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(11)" + }, + { + "name": "sort-id", + "value": "ac-04.11" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.11_smt", + "name": "statement", + "prose": "Provide the capability for privileged administrators to configure {{ insert: param, ac-4.11_prm_1 }} to support different security or privacy policies." + }, + { + "id": "ac-4.11_gdn", + "name": "guidance", + "prose": "Documentation contains detailed information for configuring security or privacy policy filters. For example, administrators can configure security or privacy policy filters to include the list of inappropriate words that security or privacy policy mechanisms check in accordance with the definitions provided by organizations." + } + ] + }, + { + "id": "ac-4.12", + "class": "SP800-53-enhancement", + "title": "Data Type Identifiers", + "params": [ + { + "id": "ac-4.12_prm_1", + "label": "organization-defined data type identifiers" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(12)" + }, + { + "name": "sort-id", + "value": "ac-04.12" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.12_smt", + "name": "statement", + "prose": "When transferring information between different security domains, use {{ insert: param, ac-4.12_prm_1 }} to validate data essential for information flow decisions." + }, + { + "id": "ac-4.12_gdn", + "name": "guidance", + "prose": "Data type identifiers include filenames, file types, file signatures or tokens, and multiple internal file signatures or tokens. Systems only allow transfer of data that is compliant with data type format specifications. Identification and validation of data types is based on defined specifications associated with each allowed data format. The filename and number alone are not used for data type identification. Content is validated syntactically and semantically against its specification to ensure that it is the proper data type." + } + ] + }, + { + "id": "ac-4.13", + "class": "SP800-53-enhancement", + "title": "Decomposition into Policy-relevant Subcomponents", + "params": [ + { + "id": "ac-4.13_prm_1", + "label": "organization-defined policy-relevant subcomponents" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(13)" + }, + { + "name": "sort-id", + "value": "ac-04.13" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.13_smt", + "name": "statement", + "prose": "When transferring information between different security domains, decompose information into {{ insert: param, ac-4.13_prm_1 }} for submission to policy enforcement mechanisms." + }, + { + "id": "ac-4.13_gdn", + "name": "guidance", + "prose": "Decomposing information into policy-relevant subcomponents prior to information transfer facilitates policy decisions on source, destination, certificates, classification, attachments, and other security- or privacy-related component differentiators. Policy enforcement mechanisms apply filtering, inspection, and/or sanitization rules to the policy-relevant subcomponents of information to facilitate flow enforcement prior to transferring such information to different security domains." + } + ] + }, + { + "id": "ac-4.14", + "class": "SP800-53-enhancement", + "title": "Security or Privacy Policy Filter Constraints", + "params": [ + { + "id": "ac-4.14_prm_1", + "label": "organization-defined security or privacy policy filters" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(14)" + }, + { + "name": "sort-id", + "value": "ac-04.14" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.14_smt", + "name": "statement", + "prose": "When transferring information between different security domains, implement {{ insert: param, ac-4.14_prm_1 }} requiring fully enumerated formats that restrict data structure and content." + }, + { + "id": "ac-4.14_gdn", + "name": "guidance", + "prose": "Data structure and content restrictions reduce the range of potential malicious or unsanctioned content in cross-domain transactions. Security or privacy policy filters that restrict data structures include restricting file sizes and field lengths. Data content policy filters include encoding formats for character sets, restricting character data fields to only contain alpha-numeric characters, prohibiting special characters, and validating schema structures." + } + ] + }, + { + "id": "ac-4.15", + "class": "SP800-53-enhancement", + "title": "Detection of Unsanctioned Information", + "params": [ + { + "id": "ac-4.15_prm_1", + "label": "organization-defined unsanctioned information" + }, + { + "id": "ac-4.15_prm_2", + "label": "organization-defined security or privacy policy" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(15)" + }, + { + "name": "sort-id", + "value": "ac-04.15" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + }, + { + "href": "#si-3", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-4.15_smt", + "name": "statement", + "prose": "When transferring information between different security domains, examine the information for the presence of {{ insert: param, ac-4.15_prm_1 }} and prohibit the transfer of such information in accordance with the {{ insert: param, ac-4.15_prm_2 }}." + }, + { + "id": "ac-4.15_gdn", + "name": "guidance", + "prose": "Unsanctioned information includes malicious code, information that is inappropriate for release from the source network, or executable code that could disrupt or harm the services or systems on the destination network." + } + ] + }, + { + "id": "ac-4.16", + "class": "SP800-53-enhancement", + "title": "Information Transfers on Interconnected Systems", + "props": [ + { + "name": "label", + "value": "AC-4(16)" + }, + { + "name": "sort-id", + "value": "ac-04.16" + }, + { + "name": "status", + "value": "withdrawn" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "incorporated-into" + } + ] + }, + { + "id": "ac-4.17", + "class": "SP800-53-enhancement", + "title": "Domain Authentication", + "params": [ + { + "id": "ac-4.17_prm_1", + "select": { + "how-many": "one-or-more", + "choice": [ + "organization", + "system", + "application", + "service", + "individual" + ] + } + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(17)" + }, + { + "name": "sort-id", + "value": "ac-04.17" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + }, + { + "href": "#ia-2", + "rel": "related" + }, + { + "href": "#ia-3", + "rel": "related" + }, + { + "href": "#ia-9", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-4.17_smt", + "name": "statement", + "prose": "Uniquely identify and authenticate source and destination points by {{ insert: param, ac-4.17_prm_1 }} for information transfer." + }, + { + "id": "ac-4.17_gdn", + "name": "guidance", + "prose": "Attribution is a critical component of a security and privacy concept of operations. The ability to identify source and destination points for information flowing within systems allows the forensic reconstruction of events and encourages policy compliance by attributing policy violations to specific organizations or individuals. Successful domain authentication requires that system labels distinguish among systems, organizations, and individuals involved in preparing, sending, receiving, or disseminating information. Attribution also allows organizations to better maintain the lineage of personally identifiable information processing as it flows through systems and can facilitate consent tracking, as well as correction, deletion, or access requests from individuals." + } + ] + }, + { + "id": "ac-4.18", + "class": "SP800-53-enhancement", + "title": "Security Attribute Binding", + "props": [ + { + "name": "label", + "value": "AC-4(18)" + }, + { + "name": "sort-id", + "value": "ac-04.18" + }, + { + "name": "status", + "value": "withdrawn" + } + ], + "links": [ + { + "href": "#ac-16", + "rel": "incorporated-into" + } + ] + }, + { + "id": "ac-4.19", + "class": "SP800-53-enhancement", + "title": "Validation of Metadata", + "params": [ + { + "id": "ac-4.19_prm_1", + "label": "organization-defined security or privacy policy filters" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(19)" + }, + { + "name": "sort-id", + "value": "ac-04.19" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.19_smt", + "name": "statement", + "prose": "When transferring information between different security domains, implement {{ insert: param, ac-4.19_prm_1 }} on metadata." + }, + { + "id": "ac-4.19_gdn", + "name": "guidance", + "prose": "All information (including metadata and the data to which the metadata applies) is subject to filtering and inspection. Some organizations distinguish between metadata and data payloads (i.e., only the data to which the metadata is bound). Other organizations do not make such distinctions and consider metadata and the data to which the metadata applies to be part of the payload." + } + ] + }, + { + "id": "ac-4.20", + "class": "SP800-53-enhancement", + "title": "Approved Solutions", + "params": [ + { + "id": "ac-4.20_prm_1", + "label": "organization-defined solutions in approved configurations" + }, + { + "id": "ac-4.20_prm_2", + "label": "organization-defined information" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(20)" + }, + { + "name": "sort-id", + "value": "ac-04.20" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.20_smt", + "name": "statement", + "prose": "Employ {{ insert: param, ac-4.20_prm_1 }} to control the flow of {{ insert: param, ac-4.20_prm_2 }} across security domains." + }, + { + "id": "ac-4.20_gdn", + "name": "guidance", + "prose": "Organizations define approved solutions and configurations in cross-domain policies and guidance in accordance with the types of information flows across classification boundaries. The National Security Agency (NSA) National Cross Domain Strategy and Management Office provides a listing of approved cross-domain solutions. Contact [ncdsmo@nsa.gov](mailto:ncdsmo@nsa.gov) for more information." + } + ] + }, + { + "id": "ac-4.21", + "class": "SP800-53-enhancement", + "title": "Physical or Logical Separation of Information Flows", + "params": [ + { + "id": "ac-4.21_prm_1", + "label": "organization-defined mechanisms and/or techniques" + }, + { + "id": "ac-4.21_prm_2", + "label": "organization-defined required separations by types of information" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(21)" + }, + { + "name": "sort-id", + "value": "ac-04.21" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + }, + { + "href": "#sc-32", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-4.21_smt", + "name": "statement", + "prose": "Separate information flows logically or physically using {{ insert: param, ac-4.21_prm_1 }} to accomplish {{ insert: param, ac-4.21_prm_2 }}." + }, + { + "id": "ac-4.21_gdn", + "name": "guidance", + "prose": "Enforcing the separation of information flows associated with defined types of data can enhance protection by ensuring that information is not commingled while in transit and by enabling flow control by transmission paths that are not otherwise achievable. Types of separable information include inbound and outbound communications traffic, service requests and responses, and information of differing security impact or classification levels." + } + ] + }, + { + "id": "ac-4.22", + "class": "SP800-53-enhancement", + "title": "Access Only", + "props": [ + { + "name": "label", + "value": "AC-4(22)" + }, + { + "name": "sort-id", + "value": "ac-04.22" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.22_smt", + "name": "statement", + "prose": "Provide access from a single device to computing platforms, applications, or data residing in multiple different security domains, while preventing information flow between the different security domains." + }, + { + "id": "ac-4.22_gdn", + "name": "guidance", + "prose": "The system provides a capability for users to access each connected security domain without providing any mechanisms to allow users to transfer data or information between the different security domains. An example of an access-only solution is a terminal that provides a user access to information with different security classifications while assuredly keeping the information separate." + } + ] + }, + { + "id": "ac-4.23", + "class": "SP800-53-enhancement", + "title": "Modify Non-releasable Information", + "params": [ + { + "id": "ac-4.23_prm_1", + "label": "organization-defined modification action" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(23)" + }, + { + "name": "sort-id", + "value": "ac-04.23" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.23_smt", + "name": "statement", + "prose": "When transferring information between different security domains, modify non-releasable information by implementing {{ insert: param, ac-4.23_prm_1 }}." + }, + { + "id": "ac-4.23_gdn", + "name": "guidance", + "prose": "Modifying non-releasable information can help prevent a data spill or attack when information is transferred across security domains. Modification actions include masking, permutation, alteration, removal, or redaction." + } + ] + }, + { + "id": "ac-4.24", + "class": "SP800-53-enhancement", + "title": "Internal Normalized Format", + "props": [ + { + "name": "label", + "value": "AC-4(24)" + }, + { + "name": "sort-id", + "value": "ac-04.24" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.24_smt", + "name": "statement", + "prose": "When transferring information between different security domains, parse incoming data into an internal normalized format and regenerate the data to be consistent with its intended specification." + }, + { + "id": "ac-4.24_gdn", + "name": "guidance", + "prose": "Converting data into normalized forms is one of most of effective mechanisms to stop malicious attacks and large classes of data exfiltration." + } + ] + }, + { + "id": "ac-4.25", + "class": "SP800-53-enhancement", + "title": "Data Sanitization", + "params": [ + { + "id": "ac-4.25_prm_1", + "select": { + "how-many": "one-or-more", + "choice": [ + "delivery of malicious content, command and control of malicious code, malicious code augmentation, and steganography encoded data", + "spillage of sensitive information" + ] + } + }, + { + "id": "ac-4.25_prm_2", + "label": "organization-defined policy" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(25)" + }, + { + "name": "sort-id", + "value": "ac-04.25" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + }, + { + "href": "#mp-6", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-4.25_smt", + "name": "statement", + "prose": "When transferring information between different security domains, sanitize data to minimize {{ insert: param, ac-4.25_prm_1 }} in accordance with {{ insert: param, ac-4.25_prm_2 }}." + }, + { + "id": "ac-4.25_gdn", + "name": "guidance", + "prose": "Data sanitization is the process of irreversibly removing or destroying data stored on a memory device (e.g., hard drives, flash memory/solid state drives, mobile devices, CDs, and DVDs) or in hard copy form." + } + ] + }, + { + "id": "ac-4.26", + "class": "SP800-53-enhancement", + "title": "Audit Filtering Actions", + "props": [ + { + "name": "label", + "value": "AC-4(26)" + }, + { + "name": "sort-id", + "value": "ac-04.26" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + }, + { + "href": "#au-2", + "rel": "related" + }, + { + "href": "#au-3", + "rel": "related" + }, + { + "href": "#au-12", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-4.26_smt", + "name": "statement", + "prose": "When transferring information between different security domains, record and audit content filtering actions and results for the information being filtered." + }, + { + "id": "ac-4.26_gdn", + "name": "guidance", + "prose": "Content filtering is the process of inspecting information as it traverses a cross-domain solution and determines if the information meets a predefined policy. Content filtering actions and the results of filtering actions are recorded for individual messages to ensure that the correct filter actions were applied. Content filter reports are used to assist in troubleshooting actions by, for example, determining why message content was modified and/or why it failed the filtering process. Audit events are defined in [AU-2](#au-2). Audit records are generated in [AU-12](#au-12)." + } + ] + }, + { + "id": "ac-4.27", + "class": "SP800-53-enhancement", + "title": "Redundant/independent Filtering Mechanisms", + "props": [ + { + "name": "label", + "value": "AC-4(27)" + }, + { + "name": "sort-id", + "value": "ac-04.27" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.27_smt", + "name": "statement", + "prose": "When transferring information between different security domains, implement content filtering solutions that provide redundant and independent filtering mechanisms for each data type." + }, + { + "id": "ac-4.27_gdn", + "name": "guidance", + "prose": "Content filtering is the process of inspecting information as it traverses a cross-domain solution and determines if the information meets a predefined policy. Redundant and independent content filtering eliminates a single point of failure filtering system. Independence is defined as the implementation of a content filter that uses a different code base and supporting libraries (e.g., two JPEG filters using different vendors’ JPEG libraries) and multiple, independent system processes." + } + ] + }, + { + "id": "ac-4.28", + "class": "SP800-53-enhancement", + "title": "Linear Filter Pipelines", + "props": [ + { + "name": "label", + "value": "AC-4(28)" + }, + { + "name": "sort-id", + "value": "ac-04.28" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.28_smt", + "name": "statement", + "prose": "When transferring information between different security domains, implement a linear content filter pipeline that is enforced with discretionary and mandatory access controls." + }, + { + "id": "ac-4.28_gdn", + "name": "guidance", + "prose": "Content filtering is the process of inspecting information as it traverses a cross-domain solution and determines if the information meets a predefined policy. The use of linear content filter pipelines ensures that filter processes are non-bypassable and always invoked. In general, the use of parallel filtering architectures for content filtering of a single data type introduces bypass and non-invocation issues." + } + ] + }, + { + "id": "ac-4.29", + "class": "SP800-53-enhancement", + "title": "Filter Orchestration Engines", + "params": [ + { + "id": "ac-4.29_prm_1", + "label": "organization-defined policy" + } + ], + "props": [ + { + "name": "label", + "value": "AC-4(29)" + }, + { + "name": "sort-id", + "value": "ac-04.29" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.29_smt", + "name": "statement", + "prose": "When transferring information between different security domains, employ content filter orchestration engines to ensure that:", + "parts": [ + { + "id": "ac-4.29_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Content filtering mechanisms successfully complete execution without errors; and" + }, + { + "id": "ac-4.29_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Content filtering actions occur in the correct order and comply with {{ insert: param, ac-4.29_prm_1 }}." + } + ] + }, + { + "id": "ac-4.29_gdn", + "name": "guidance", + "prose": "Content filtering is the process of inspecting information as it traverses a cross-domain solution and determines if the information meets a predefined security policy. An orchestration engine coordinates the sequencing of activities (manual and automated) in a content filtering process. Errors are defined as either anomalous actions or unexpected termination of the content filter process. This is not the same as a filter failing content due to non-compliance with policy. Content filter reports are a commonly used mechanism to ensure that expected filtering actions are completed successfully." + } + ] + }, + { + "id": "ac-4.30", + "class": "SP800-53-enhancement", + "title": "Filter Mechanisms Using Multiple Processes", + "props": [ + { + "name": "label", + "value": "AC-4(30)" + }, + { + "name": "sort-id", + "value": "ac-04.30" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.30_smt", + "name": "statement", + "prose": "When transferring information between different security domains, implement content filtering mechanisms using multiple processes." + }, + { + "id": "ac-4.30_gdn", + "name": "guidance", + "prose": "The use of multiple processes to implement content filtering mechanisms reduces the likelihood of a single point of failure." + } + ] + }, + { + "id": "ac-4.31", + "class": "SP800-53-enhancement", + "title": "Failed Content Transfer Prevention", + "props": [ + { + "name": "label", + "value": "AC-4(31)" + }, + { + "name": "sort-id", + "value": "ac-04.31" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.31_smt", + "name": "statement", + "prose": "When transferring information between different security domains, prevent the transfer of failed content to the receiving domain." + }, + { + "id": "ac-4.31_gdn", + "name": "guidance", + "prose": "Content that failed filtering checks can corrupt the system if transferred to the receiving domain." + } + ] + }, + { + "id": "ac-4.32", + "class": "SP800-53-enhancement", + "title": "Process Requirements for Information Transfer", + "props": [ + { + "name": "label", + "value": "AC-4(32)" + }, + { + "name": "sort-id", + "value": "ac-04.32" + } + ], + "links": [ + { + "href": "#ac-4", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-4.32_smt", + "name": "statement", + "prose": "When transferring information between different security domains, the process that transfers information between filter pipelines:", + "parts": [ + { + "id": "ac-4.32_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Does not filter message content;" + }, + { + "id": "ac-4.32_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Validates filtering metadata;" + }, + { + "id": "ac-4.32_smt.c", + "name": "item", + "props": [ + { + "name": "label", + "value": "(c)" + } + ], + "prose": "Ensures the content associated with the filtering metadata has successfully completed filtering; and" + }, + { + "id": "ac-4.32_smt.d", + "name": "item", + "props": [ + { + "name": "label", + "value": "(d)" + } + ], + "prose": "Transfers the content to the destination filter pipeline." + } + ] + }, + { + "id": "ac-4.32_gdn", + "name": "guidance", + "prose": "The processes transferring information between filter pipelines have minimum complexity and functionality to provide assurance that the processes operate correctly." + } + ] + } + ] + }, + { + "id": "ac-5", + "class": "SP800-53", + "title": "Separation of Duties", + "params": [ + { + "id": "ac-5_prm_1", + "label": "organization-defined duties of individuals requiring separation" + } + ], + "props": [ + { + "name": "label", + "value": "AC-5" + }, + { + "name": "sort-id", + "value": "ac-05" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "related" + }, + { + "href": "#ac-3", + "rel": "related" + }, + { + "href": "#ac-6", + "rel": "related" + }, + { + "href": "#au-9", + "rel": "related" + }, + { + "href": "#cm-5", + "rel": "related" + }, + { + "href": "#cm-11", + "rel": "related" + }, + { + "href": "#cp-9", + "rel": "related" + }, + { + "href": "#ia-2", + "rel": "related" + }, + { + "href": "#ia-4", + "rel": "related" + }, + { + "href": "#ia-5", + "rel": "related" + }, + { + "href": "#ia-12", + "rel": "related" + }, + { + "href": "#ma-3", + "rel": "related" + }, + { + "href": "#ma-5", + "rel": "related" + }, + { + "href": "#ps-2", + "rel": "related" + }, + { + "href": "#sa-8", + "rel": "related" + }, + { + "href": "#sa-17", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-5_smt", + "name": "statement", + "parts": [ + { + "id": "ac-5_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "a." + } + ], + "prose": "Identify and document {{ insert: param, ac-5_prm_1 }}; and" + }, + { + "id": "ac-5_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "b." + } + ], + "prose": "Define system access authorizations to support separation of duties." + } + ] + }, + { + "id": "ac-5_gdn", + "name": "guidance", + "prose": "Separation of duties addresses the potential for abuse of authorized privileges and helps to reduce the risk of malevolent activity without collusion. Separation of duties includes dividing mission or business functions and support functions among different individuals or roles, conducting system support functions with different individuals, and ensuring that security personnel who administer access control functions do not also administer audit functions. Because separation of duty violations can span systems and application domains, organizations consider the entirety of systems and system components when developing policy on separation of duties. Separation of duties is enforced through the account management activities in [AC-2](#ac-2), access control mechanisms in [AC-3](#ac-3), and identity management activities in [IA-2](#ia-2), [IA-4](#ia-4), and [IA-12](#ia-12)." + } + ] + }, + { + "id": "ac-6", + "class": "SP800-53", + "title": "Least Privilege", + "props": [ + { + "name": "label", + "value": "AC-6" + }, + { + "name": "sort-id", + "value": "ac-06" + } + ], + "links": [ + { + "href": "#ac-2", + "rel": "related" + }, + { + "href": "#ac-3", + "rel": "related" + }, + { + "href": "#ac-5", + "rel": "related" + }, + { + "href": "#ac-16", + "rel": "related" + }, + { + "href": "#cm-5", + "rel": "related" + }, + { + "href": "#cm-11", + "rel": "related" + }, + { + "href": "#pl-2", + "rel": "related" + }, + { + "href": "#pm-12", + "rel": "related" + }, + { + "href": "#sa-8", + "rel": "related" + }, + { + "href": "#sa-15", + "rel": "related" + }, + { + "href": "#sa-17", + "rel": "related" + }, + { + "href": "#sc-38", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-6_smt", + "name": "statement", + "prose": "Employ the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) that are necessary to accomplish assigned organizational tasks." + }, + { + "id": "ac-6_gdn", + "name": "guidance", + "prose": "Organizations employ least privilege for specific duties and systems. The principle of least privilege is also applied to system processes, ensuring that the processes have access to systems and operate at privilege levels no higher than necessary to accomplish organizational missions or business functions. Organizations consider the creation of additional processes, roles, and accounts as necessary to achieve least privilege. Organizations apply least privilege to the development, implementation, and operation of organizational systems." + } + ], + "controls": [ + { + "id": "ac-6.1", + "class": "SP800-53-enhancement", + "title": "Authorize Access to Security Functions", + "params": [ + { + "id": "ac-6.1_prm_1", + "label": "organization-defined individuals or roles" + }, + { + "id": "ac-6.1_prm_2", + "label": "organization-defined security functions (deployed in hardware, software, and firmware)" + }, + { + "id": "ac-6.1_prm_3", + "label": "organization-defined security-relevant information" + } + ], + "props": [ + { + "name": "label", + "value": "AC-6(1)" + }, + { + "name": "sort-id", + "value": "ac-06.01" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "required" + }, + { + "href": "#ac-17", + "rel": "related" + }, + { + "href": "#ac-18", + "rel": "related" + }, + { + "href": "#ac-19", + "rel": "related" + }, + { + "href": "#au-9", + "rel": "related" + }, + { + "href": "#pe-2", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-6.1_smt", + "name": "statement", + "prose": "Authorize access for {{ insert: param, ac-6.1_prm_1 }} to:", + "parts": [ + { + "id": "ac-6.1_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": " {{ insert: param, ac-6.1_prm_2 }}; and" + }, + { + "id": "ac-6.1_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": " {{ insert: param, ac-6.1_prm_3 }}." + } + ] + }, + { + "id": "ac-6.1_gdn", + "name": "guidance", + "prose": "Security functions include establishing system accounts, configuring access authorizations (i.e., permissions, privileges), configuring settings for events to be audited, and establishing intrusion detection parameters. Security-relevant information includes filtering rules for routers or firewalls, configuration parameters for security services, cryptographic key management information, and access control lists. Authorized personnel include security administrators, system administrators, system security officers, system programmers, and other privileged users." + } + ] + }, + { + "id": "ac-6.2", + "class": "SP800-53-enhancement", + "title": "Non-privileged Access for Nonsecurity Functions", + "params": [ + { + "id": "ac-6.2_prm_1", + "label": "organization-defined security functions or security-relevant information" + } + ], + "props": [ + { + "name": "label", + "value": "AC-6(2)" + }, + { + "name": "sort-id", + "value": "ac-06.02" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "required" + }, + { + "href": "#ac-17", + "rel": "related" + }, + { + "href": "#ac-18", + "rel": "related" + }, + { + "href": "#ac-19", + "rel": "related" + }, + { + "href": "#pl-4", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-6.2_smt", + "name": "statement", + "prose": "Require that users of system accounts (or roles) with access to {{ insert: param, ac-6.2_prm_1 }} use non-privileged accounts or roles, when accessing nonsecurity functions." + }, + { + "id": "ac-6.2_gdn", + "name": "guidance", + "prose": "Requiring the use of non-privileged accounts when accessing nonsecurity functions limits exposure when operating from within privileged accounts or roles. The inclusion of roles addresses situations where organizations implement access control policies, such as role-based access control, and where a change of role provides the same degree of assurance in the change of access authorizations for the user and the processes acting on behalf of the user as would be provided by a change between a privileged and non-privileged account." + } + ] + }, + { + "id": "ac-6.3", + "class": "SP800-53-enhancement", + "title": "Network Access to Privileged Commands", + "params": [ + { + "id": "ac-6.3_prm_1", + "label": "organization-defined privileged commands" + }, + { + "id": "ac-6.3_prm_2", + "label": "organization-defined compelling operational needs" + } + ], + "props": [ + { + "name": "label", + "value": "AC-6(3)" + }, + { + "name": "sort-id", + "value": "ac-06.03" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "required" + }, + { + "href": "#ac-17", + "rel": "related" + }, + { + "href": "#ac-18", + "rel": "related" + }, + { + "href": "#ac-19", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-6.3_smt", + "name": "statement", + "prose": "Authorize network access to {{ insert: param, ac-6.3_prm_1 }} only for {{ insert: param, ac-6.3_prm_2 }} and document the rationale for such access in the security plan for the system." + }, + { + "id": "ac-6.3_gdn", + "name": "guidance", + "prose": "Network access is any access across a network connection in lieu of local access (i.e., user being physically present at the device)." + } + ] + }, + { + "id": "ac-6.4", + "class": "SP800-53-enhancement", + "title": "Separate Processing Domains", + "props": [ + { + "name": "label", + "value": "AC-6(4)" + }, + { + "name": "sort-id", + "value": "ac-06.04" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "required" + }, + { + "href": "#ac-4", + "rel": "related" + }, + { + "href": "#sc-2", + "rel": "related" + }, + { + "href": "#sc-3", + "rel": "related" + }, + { + "href": "#sc-30", + "rel": "related" + }, + { + "href": "#sc-32", + "rel": "related" + }, + { + "href": "#sc-39", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-6.4_smt", + "name": "statement", + "prose": "Provide separate processing domains to enable finer-grained allocation of user privileges." + }, + { + "id": "ac-6.4_gdn", + "name": "guidance", + "prose": "Providing separate processing domains for finer-grained allocation of user privileges includes using virtualization techniques to permit additional user privileges within a virtual machine while restricting privileges to other virtual machines or to the underlying physical machine, implementing separate physical domains, and employing hardware or software domain separation mechanisms." + } + ] + }, + { + "id": "ac-6.5", + "class": "SP800-53-enhancement", + "title": "Privileged Accounts", + "params": [ + { + "id": "ac-6.5_prm_1", + "label": "organization-defined personnel or roles" + } + ], + "props": [ + { + "name": "label", + "value": "AC-6(5)" + }, + { + "name": "sort-id", + "value": "ac-06.05" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "required" + }, + { + "href": "#ia-2", + "rel": "related" + }, + { + "href": "#ma-3", + "rel": "related" + }, + { + "href": "#ma-4", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-6.5_smt", + "name": "statement", + "prose": "Restrict privileged accounts on the system to {{ insert: param, ac-6.5_prm_1 }}." + }, + { + "id": "ac-6.5_gdn", + "name": "guidance", + "prose": "Privileged accounts, including super user accounts, are typically described as system administrator for various types of commercial off-the-shelf operating systems. Restricting privileged accounts to specific personnel or roles prevents day-to-day users from accessing privileged information or privileged functions. Organizations may differentiate in the application of restricting privileged accounts between allowed privileges for local accounts and for domain accounts provided that they retain the ability to control system configurations for key parameters and as otherwise necessary to sufficiently mitigate risk." + } + ] + }, + { + "id": "ac-6.6", + "class": "SP800-53-enhancement", + "title": "Privileged Access by Non-organizational Users", + "props": [ + { + "name": "label", + "value": "AC-6(6)" + }, + { + "name": "sort-id", + "value": "ac-06.06" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "required" + }, + { + "href": "#ac-18", + "rel": "related" + }, + { + "href": "#ac-19", + "rel": "related" + }, + { + "href": "#ia-2", + "rel": "related" + }, + { + "href": "#ia-8", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-6.6_smt", + "name": "statement", + "prose": "Prohibit privileged access to the system by non-organizational users." + }, + { + "id": "ac-6.6_gdn", + "name": "guidance", + "prose": "An organizational user is an employee or an individual considered by the organization to have the equivalent status of an employee. Organizational users include contractors, guest researchers, or individuals detailed from other organizations. A non-organizational user is a user who is not an organizational user. Policies and procedures for granting equivalent status of employees to individuals include a need-to-know, citizenship, and the relationship to the organization." + } + ] + }, + { + "id": "ac-6.7", + "class": "SP800-53-enhancement", + "title": "Review of User Privileges", + "params": [ + { + "id": "ac-6.7_prm_1", + "label": "organization-defined frequency" + }, + { + "id": "ac-6.7_prm_2", + "label": "organization-defined roles or classes of users" + } + ], + "props": [ + { + "name": "label", + "value": "AC-6(7)" + }, + { + "name": "sort-id", + "value": "ac-06.07" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "required" + }, + { + "href": "#ca-7", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-6.7_smt", + "name": "statement", + "parts": [ + { + "id": "ac-6.7_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Review {{ insert: param, ac-6.7_prm_1 }} the privileges assigned to {{ insert: param, ac-6.7_prm_2 }} to validate the need for such privileges; and" + }, + { + "id": "ac-6.7_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Reassign or remove privileges, if necessary, to correctly reflect organizational mission and business needs." + } + ] + }, + { + "id": "ac-6.7_gdn", + "name": "guidance", + "prose": "The need for certain assigned user privileges may change over time to reflect changes in organizational mission and business functions, environments of operation, technologies, or threats. A periodic review of assigned user privileges is necessary to determine if the rationale for assigning such privileges remains valid. If the need cannot be revalidated, organizations take appropriate corrective actions." + } + ] + }, + { + "id": "ac-6.8", + "class": "SP800-53-enhancement", + "title": "Privilege Levels for Code Execution", + "params": [ + { + "id": "ac-6.8_prm_1", + "label": "organization-defined software" + } + ], + "props": [ + { + "name": "label", + "value": "AC-6(8)" + }, + { + "name": "sort-id", + "value": "ac-06.08" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-6.8_smt", + "name": "statement", + "prose": "Prevent the following software from executing at higher privilege levels than users executing the software: {{ insert: param, ac-6.8_prm_1 }}." + }, + { + "id": "ac-6.8_gdn", + "name": "guidance", + "prose": "In certain situations, software applications or programs need to execute with elevated privileges to perform required functions. However, depending on the software functionality and configuration, if the privileges required for execution are at a higher level than the privileges assigned to organizational users invoking such applications or programs, those users may indirectly be provided with greater privileges than assigned." + } + ] + }, + { + "id": "ac-6.9", + "class": "SP800-53-enhancement", + "title": "Log Use of Privileged Functions", + "props": [ + { + "name": "label", + "value": "AC-6(9)" + }, + { + "name": "sort-id", + "value": "ac-06.09" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "required" + }, + { + "href": "#au-2", + "rel": "related" + }, + { + "href": "#au-3", + "rel": "related" + }, + { + "href": "#au-12", + "rel": "related" + } + ], + "parts": [ + { + "id": "ac-6.9_smt", + "name": "statement", + "prose": "Log the execution of privileged functions." + }, + { + "id": "ac-6.9_gdn", + "name": "guidance", + "prose": "The misuse of privileged functions, either intentionally or unintentionally by authorized users or by unauthorized external entities that have compromised system accounts, is a serious and ongoing concern and can have significant adverse impacts on organizations. Logging and analyzing the use of privileged functions is one way to detect such misuse and, in doing so, help mitigate the risk from insider threats and the advanced persistent threat." + } + ] + }, + { + "id": "ac-6.10", + "class": "SP800-53-enhancement", + "title": "Prohibit Non-privileged Users from Executing Privileged Functions", + "props": [ + { + "name": "label", + "value": "AC-6(10)" + }, + { + "name": "sort-id", + "value": "ac-06.10" + } + ], + "links": [ + { + "href": "#ac-6", + "rel": "required" + } + ], + "parts": [ + { + "id": "ac-6.10_smt", + "name": "statement", + "prose": "Prevent non-privileged users from executing privileged functions." + }, + { + "id": "ac-6.10_gdn", + "name": "guidance", + "prose": "Privileged functions include disabling, circumventing, or altering implemented security or privacy controls, establishing system accounts, performing system integrity checks, and administering cryptographic key management activities. Non-privileged users are individuals who do not possess appropriate authorizations. Privileged functions that require protection from non-privileged users include circumventing intrusion detection and prevention mechanisms or malicious code protection mechanisms. Preventing non-privileged users from executing privileged functions is enforced by [AC-3](#ac-3)." + } + ] + } + ] + } + ] + }, + { + "id": "at", + "class": "family", + "title": "Awareness and Training", + "controls": [ + { + "id": "at-1", + "class": "SP800-53", + "title": "Policy and Procedures", + "params": [ + { + "id": "at-1_prm_1", + "label": "organization-defined personnel or roles" + }, + { + "id": "at-1_prm_2", + "select": { + "how-many": "one-or-more", + "choice": [ + "Organization-level", + "Mission/business process-level" + ] + } + } + ], + "props": [ + { + "name": "label", + "value": "AT-1" + }, + { + "name": "sort-id", + "value": "at-01" + } + ], + "links": [ + { + "href": "#27847491-5ce1-4f6a-a1e4-9e483782f0ef", + "rel": "reference" + }, + { + "href": "#c7ac44e8-10db-4b64-b2b9-9e32ec1efed0", + "rel": "reference" + } + ], + "parts": [ + { + "id": "at-1_smt", + "name": "statement", + "parts": [ + { + "id": "at-1_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "a." + } + ], + "prose": "Develop, document, and disseminate to {{ insert: param, at-1_prm_1 }}:", + "parts": [ + { + "id": "at-1_smt.a.1", + "name": "item", + "props": [ + { + "name": "label", + "value": "1." + } + ], + "prose": " {{ insert: param, at-1_prm_2 }} awareness and training policy that:", + "parts": [ + { + "id": "at-1_smt.a.1.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "(a)" + } + ], + "prose": "Addresses purpose, scope, roles, responsibilities, management commitment, coordination among organizational entities, and compliance; and" + }, + { + "id": "at-1_smt.a.1.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "(b)" + } + ], + "prose": "Is consistent with applicable laws, executive orders, directives, regulations, policies, standards, and guidelines; and" + } + ] + }, + { + "id": "at-1_smt.a.2", + "name": "item", + "props": [ + { + "name": "label", + "value": "2." + } + ], + "prose": "Procedures to facilitate the implementation of the awareness and training policy and the associated awareness and training controls;" + } + ] + }, + { + "id": "at-1_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "b." + } + ], + "prose": "Designate an {{ insert: param, at-1_prm_1 }} to manage the development, documentation, and dissemination of the awareness and training policy and procedures; and" + } + ] + }, + { + "id": "at-1_gdn", + "name": "guidance", + "prose": "Awareness and training policy and procedures address the controls in the AT family that are implemented within systems and organizations. The risk management strategy is an important factor in establishing such policies and procedures. Policies and procedures contribute to security and privacy assurance. Therefore, it is important that security and privacy programs collaborate on the development of awareness and training policy and procedures. Security and privacy program policies and procedures at the organization level are preferable, in general, and may obviate the need for mission- or system-specific policies and procedures. The policy can be included as part of the general security and privacy policy or be represented by multiple policies that reflect the complex nature of organizations. Procedures can be established for security and privacy programs, for mission or business processes, and for systems, if needed. Procedures describe how the policies or controls are implemented and can be directed at the individual or role that is the object of the procedure. Procedures can be documented in system security and privacy plans or in one or more separate documents. Events that may precipitate an update to awareness and training policy and procedures include assessment or audit findings, security incidents or breaches, or changes in applicable laws, executive orders, directives, regulations, policies, standards, and guidelines. Simply restating controls does not constitute an organizational policy or procedure." + } + ] + }, + { + "id": "at-2", + "class": "SP800-53", + "title": "Literacy Training and Awareness", + "params": [ + { + "id": "at-2_prm_1", + "label": "organization-defined frequency" + }, + { + "id": "at-2_prm_2", + "label": "organization-defined events" + } + ], + "props": [ + { + "name": "label", + "value": "AT-2" + }, + { + "name": "sort-id", + "value": "at-02" + } + ], + "links": [ + { + "href": "#27847491-5ce1-4f6a-a1e4-9e483782f0ef", + "rel": "reference" + }, + { + "href": "#511f6832-23ca-49a3-8c0f-ce493373cab8", + "rel": "reference" + } + ], + "parts": [ + { + "id": "at-2_smt", + "name": "statement", + "parts": [ + { + "id": "at-2_smt.a", + "name": "item", + "props": [ + { + "name": "label", + "value": "a." + } + ], + "prose": "Provide security and privacy literacy training to system users (including managers, senior executives, and contractors):", + "parts": [ + { + "id": "at-2_smt.a.1", + "name": "item", + "props": [ + { + "name": "label", + "value": "1." + } + ], + "prose": "As part of initial training for new users and {{ insert: param, at-2_prm_1 }} thereafter; and" + }, + { + "id": "at-2_smt.a.2", + "name": "item", + "props": [ + { + "name": "label", + "value": "2." + } + ], + "prose": "When required by system changes or following {{ insert: param, at-2_prm_2 }};" + } + ] + }, + { + "id": "at-2_smt.b", + "name": "item", + "props": [ + { + "name": "label", + "value": "b." + } + ], + "prose": "Employ the following techniques to increase the security and privacy awareness of system users {{ insert: param, at-2_prm_1 }};" + } + ] + }, + { + "id": "at-2_gdn", + "name": "guidance", + "prose": "Organizations provide basic and advanced levels of literacy training to system users, including measures to test the knowledge level of users. Organizations determine the content of literacy training and awareness based on specific organizational requirements, the systems to which personnel have authorized access, and work environments (e.g., telework). The content includes an understanding of the need for security and privacy as well as actions by users to maintain security and personal privacy and to respond to suspected incidents. The content addresses the need for operations security and the handling of personally identifiable information.\n\nAwareness techniques include displaying posters, offering supplies inscribed with security and privacy reminders, displaying logon screen messages, generating email advisories or notices from organizational officials, and conducting awareness events. Literacy training after the initial training described in [AT-2a.1](#at-2_smt.a.1) is conducted at a minimum frequency consistent with applicable laws, directives, regulations, and policies. Subsequent literacy training may be satisfied by one or more short ad hoc sessions and include topical information on recent attack schemes, changes to organizational security and privacy policies, revised security and privacy expectations, or a subset of topics from the initial training. Updating literacy training and awareness content on a regular basis helps to ensure that the content remains relevant. Events that may precipitate an update to literacy training and awareness content include, but are not limited to, assessment or audit findings, security incidents or breaches, or changes in applicable laws, executive orders, directives, regulations, policies, standards, and guidelines." + } + ], + "controls": [ + { + "id": "at-2.1", + "class": "SP800-53-enhancement", + "title": "Practical Exercises", + "props": [ + { + "name": "label", + "value": "AT-2(1)" + }, + { + "name": "sort-id", + "value": "at-02.01" + } + ], + "links": [ + { + "href": "#at-2", + "rel": "required" + }, + { + "href": "#ca-2", + "rel": "related" + } + ], + "parts": [ + { + "id": "at-2.1_smt", + "name": "statement", + "prose": "Provide practical exercises in literacy training that simulate events and incidents." + }, + { + "id": "at-2.1_gdn", + "name": "guidance", + "prose": "Practical exercises include no-notice social engineering attempts to collect information, gain unauthorized access, or simulate the adverse impact of opening malicious email attachments or invoking, via spear phishing attacks, malicious web links." + } + ] + }, + { + "id": "at-2.2", + "class": "SP800-53-enhancement", + "title": "Insider Threat", + "props": [ + { + "name": "label", + "value": "AT-2(2)" + }, + { + "name": "sort-id", + "value": "at-02.02" + } + ], + "links": [ + { + "href": "#at-2", + "rel": "required" + }, + { + "href": "#pm-12", + "rel": "related" + } + ], + "parts": [ + { + "id": "at-2.2_smt", + "name": "statement", + "prose": "Provide literacy training on recognizing and reporting potential indicators of insider threat." + }, + { + "id": "at-2.2_gdn", + "name": "guidance", + "prose": "Potential indicators and possible precursors of insider threat can include behaviors such as inordinate, long-term job dissatisfaction; attempts to gain access to information not required for job performance; unexplained access to financial resources; bullying or harassment of fellow employees; workplace violence; and other serious violations of policies, procedures, directives, regulations, rules, or practices. Literacy training includes how to communicate the concerns of employees and management regarding potential indicators of insider threat through channels established by the organization and in accordance with established policies and procedures. Organizations may consider tailoring insider threat awareness topics to the role. For example, training for managers may be focused on changes in the behavior of team members, while training for employees may be focused on more general observations." + } + ] + } + ] + } + ] + } + ], + "back-matter": { + "resources": [ + { + "uuid": "91f992fb-f668-4c91-a50f-0f05b95ccee3", + "title": "32 CFR 2002", + "citation": { + "text": "Code of Federal Regulations, Title 32, *Controlled Unclassified Information* (32 C.F.R. 2002)." + }, + "rlinks": [ + { + "href": "https://www.federalregister.gov/documents/2016/09/14/2016-21665/controlled-unclassified-information" + } + ] + }, + { + "uuid": "0f963c17-ab5a-432a-a867-91eac550309b", + "title": "41 CFR 201", + "citation": { + "text": " \"Federal Acquisition Supply Chain Security Act; Rule,\" 85 Federal Register 54263 (September 1, 2020), pp 54263-54271." + }, + "rlinks": [ + { + "href": "https://www.federalregister.gov/d/2020-18939" + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/tests/data/json/simplified_nist_profile.json b/tests/data/json/simplified_nist_profile.json new file mode 100644 index 00000000..31d5ca50 --- /dev/null +++ b/tests/data/json/simplified_nist_profile.json @@ -0,0 +1,142 @@ +{ + "profile": { + "uuid": "1019f424-1556-4aa3-9df3-337b97c2c856", + "metadata": { + "title": "NIST Special Publication 800-53 Revision 5 MODERATE IMPACT BASELINE", + "last-modified": "2021-06-08T13:57:34.337491-04:00", + "version": "Final", + "oscal-version": "1.0.0", + "roles": [ + { + "id": "creator", + "title": "Document Creator" + }, + { + "id": "contact", + "title": "Contact" + } + ], + "parties": [ + { + "uuid": "cde369ce-57f8-4ec1-847f-2681a9a881e7", + "type": "organization", + "name": "Joint Task Force, Transformation Initiative", + "email-addresses": [ + "sec-cert@nist.gov" + ], + "addresses": [ + { + "addr-lines": [ + "National Institute of Standards and Technology", + "Attn: Computer Security Division", + "Information Technology Laboratory", + "100 Bureau Drive (Mail Stop 8930)" + ], + "city": "Gaithersburg", + "state": "MD", + "postal-code": "20899-8930" + } + ] + } + ], + "responsible-parties": [ + { + "role-id": "creator", + "party-uuids": [ + "cde369ce-57f8-4ec1-847f-2681a9a881e7" + ] + }, + { + "role-id": "contact", + "party-uuids": [ + "cde369ce-57f8-4ec1-847f-2681a9a881e7" + ] + } + ] + }, + "imports": [ + { + "href": "trestle://catalogs/simplified_nist_catalog/catalog.json", + "include-controls": [ + { + "with-ids": [ + "ac-1", + "ac-2", + "ac-2.1", + "ac-2.2", + "ac-2.3", + "ac-2.4", + "ac-2.5", + "ac-2.13", + "ac-3", + "ac-4", + "ac-4.4", + "ac-5" + ] + } + ] + } + ], + "merge": { + "as-is": true + }, + "modify": { + "set-parameters": [ + { + "param_id": "ac-1_prm_1", + "class": "newclassfromprof", + "depends-on": "newdependsonfromprof", + "usage": "new usage from prof", + "props": [ + { + "name": "param_1_prop", + "value": "prop value from prof" + }, + { + "name": "param_1_prop_2", + "value": "new prop value from prof" + } + ], + "links": [ + { + "href": "#123456789", + "text": "new text from prof" + }, + { + "href": "#new_link", + "text": "new link text" + } + ], + "constraints": [ + { + "description": "new constraint" + } + ], + "guidelines": [ + { + "prose": "new guideline" + } + ] + }, + { + "param_id": "ac-4.4_prm_3", + "values": [ + "hacking the system" + ] + }, + { + "param_id": "loose_2", + "values": [ + "loose_2_val_from_prof" + ] + }, + { + "param_id": "bad_param_id", + "values": [ + "this will cause warning" + ] + } + ] + } + } +} diff --git a/tests/data/json/test_comp.json b/tests/data/json/test_comp.json new file mode 100644 index 00000000..44e92d8d --- /dev/null +++ b/tests/data/json/test_comp.json @@ -0,0 +1,273 @@ +{ + "component-definition": { + "uuid": "2652b814-2a6b-4b6d-a0ae-8bc7a007209f", + "metadata": { + "title": "comp def a", + "last-modified": "2021-07-19T14:03:03+00:00", + "version": "0.21.0", + "oscal-version": "1.0.2", + "roles": [ + { + "id": "prepared-by", + "title": "Indicates the organization that created this content." + }, + { + "id": "prepared-for", + "title": "Indicates the organization for which this content was created.." + }, + { + "id": "content-approver", + "title": "Indicates the organization responsible for all content represented in the \"document\"." + } + ], + "parties": [ + { + "uuid": "ce1f379a-fcdd-485a-a7b7-6f02c0763dd2", + "type": "organization", + "name": "ACME", + "remarks": "ACME company" + }, + { + "uuid": "481856b6-16e4-4993-a3ed-2fb242ce235b", + "type": "organization", + "name": "Customer", + "remarks": "Customer for the Component Definition" + }, + { + "uuid": "2dc8b17f-daca-44a1-8a1d-c290120ea5e2", + "type": "organization", + "name": "ISV", + "remarks": "ISV for the Component Definition" + } + ], + "responsible-parties": [ + { + "role-id": "prepared-by", + "party-uuids": [ + "ce1f379a-fcdd-485a-a7b7-6f02c0763dd2" + ] + }, + { + "role-id": "prepared-for", + "party-uuids": [ + "481856b6-16e4-4993-a3ed-2fb242ce235b", + "2dc8b17f-daca-44a1-8a1d-c290120ea5e2" + ] + }, + { + "role-id": "content-approver", + "party-uuids": [ + "ce1f379a-fcdd-485a-a7b7-6f02c0763dd2" + ] + } + ] + }, + "components": [ + { + "uuid": "8220b305-0271-45f9-8a21-40ab6f197f70", + "type": "Service", + "title": "test comp", + "description": "test comp", + "props": [ + { + "name": "Rule_Id", + "ns": "http://comp_ns", + "value": "top_shared_rule_1", + "class": "Rule_Id", + "remarks": "rule_1" + }, + { + "name": "Rule_Description", + "ns": "http://comp_ns", + "value": "top shared rule 1 in aa", + "remarks": "rule_1" + }, + { + "name": "Parameter_Id", + "ns": "http://comp_ns", + "value": "shared_param_x", + "class": "Parameter_Id", + "remarks": "rule_x" + }, + { + "name": "Parameter_Description", + "ns": "http://comp_ns", + "value": "shared param x in aa", + "class": "Parameter_Description", + "remarks": "rule_x" + }, + { + "name": "Parameter_Value_Alternatives", + "ns": "http://comp_ns", + "value": "[\"shared_param_x_aa_opt_1\", \"shared_param_x_aa_opt_2\", \"shared_param_x_aa_opt_3\"]", + "class": "Parameter_Value_Alternatives", + "remarks": "rule_x" + } + ], + "control-implementations": [ + { + "uuid": "76e89b67-3d6b-463d-90df-ec56a46c6069", + "source": "trestle://profiles/simplified_nist_profile/profile.json", + "description": "test comp", + "props": [ + { + "name": "profile_name", + "ns": "https://trestle/prof_ns", + "value": "trestle prof aa", + "class": "trestle_profile_name" + }, + { + "name": "Rule_Id", + "ns": "http://comp_ns", + "value": "comp_rule_aa_1", + "class": "Rule_Id", + "remarks": "rule_2" + }, + { + "name": "Rule_Description", + "ns": "http://comp_ns", + "value": "comp rule aa 1", + "remarks": "rule_2" + }, + { + "name": "Rule_Id", + "ns": "http://comp_ns", + "value": "comp_rule_aa_2", + "class": "Rule_Id", + "remarks": "rule_3" + }, + { + "name": "Rule_Description", + "ns": "http://comp_ns", + "value": "comp rule aa 2", + "class": "Rule_Description", + "remarks": "rule_3" + }, + { + "name": "Parameter_Id", + "ns": "http://comp_ns", + "value": "shared_param_1", + "class": "Parameter_Id", + "remarks": "rule_1" + }, + { + "name": "Parameter_Description", + "ns": "http://comp_ns", + "value": "shared param 1 in aa", + "class": "Parameter_Description", + "remarks": "rule_1" + }, + { + "name": "Parameter_Value_Alternatives", + "ns": "http://comp_ns", + "value": "[\"shared_param_1_aa_opt_1\", \"shared_param_1_aa_opt_2\", \"shared_param_1_aa_opt_3\"]", + "class": "Parameter_Value_Alternatives", + "remarks": "rule_1" + } + ], + "set-parameters": [ + { + "param-id": "shared_param_1", + "values": [ + "shared_param_1_aa_opt_1" + ], + "remarks": "set shared param aa 3" + }, + { + "param-id": "ac-1_prm_3", + "values": [ + "set by comp aa ci" + ] + } + ], + "implemented-requirements": [ + { + "uuid": "ca5ea4c5-ba51-4b1d-932a-5606891b7500", + "control-id": "ac-1", + "description": "imp req prose for ac-1 from comp aa", + "props": [ + { + "name": "Rule_Id", + "value": "top_shared_rule_1" + }, + { + "name": "implementation-status", + "value": "implemented" + } + ], + "set-parameters": [ + { + "param-id": "shared_param_1", + "values": [ + "shared_param_1_aa_opt_1" + ], + "remarks": "set shared param aa 1" + }, + { + "param-id": "ac-1_prm_3", + "values": [ + "set by comp aa imp req" + ] + } + ], + "responsible-roles": [ + { + "role-id": "prepared-by", + "party-uuids": [ + "ce1f379a-fcdd-485a-a7b7-6f02c0763dd2" + ] + }, + { + "role-id": "prepared-for", + "party-uuids": [ + "481856b6-16e4-4993-a3ed-2fb242ce235b", + "2dc8b17f-daca-44a1-8a1d-c290120ea5e2" + ] + }, + { + "role-id": "content-approver", + "party-uuids": [ + "ce1f379a-fcdd-485a-a7b7-6f02c0763dd2" + ] + } + ], + "statements": [ + { + "statement-id": "ac-1_smt.a", + "uuid": "2652b814-2a6b-4b6d-a0ae-8bc7a0072200", + "description": "statement prose for part a. from comp aa", + "props": [ + { + "name": "Rule_Id", + "value": "comp_rule_aa_1" + }, + { + "name": "implementation-status", + "value": "partial" + } + ] + } + ] + }, + { + "uuid": "ca5ea4c5-ba51-4b1d-932a-5606891b7599", + "control-id": "ac-3", + "description": "imp req prose for ac-3 from comp aa", + "props": [ + { + "name": "Rule_Id", + "value": "top_shared_rule_1" + }, + { + "name": "implementation-status", + "value": "implemented" + } + ] + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/tests/testutils.py b/tests/testutils.py new file mode 100644 index 00000000..07e8f670 --- /dev/null +++ b/tests/testutils.py @@ -0,0 +1,159 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Helper functions for unit test setup and teardown.""" + +import argparse +import pathlib +import shutil +from typing import Optional + +from git.repo import Repo +from trestle.common.model_utils import ModelUtils +from trestle.core.base_model import OscalBaseModel +from trestle.core.models.file_content_type import FileContentType +from trestle.oscal import catalog as cat +from trestle.oscal import component as comp +from trestle.oscal import profile as prof + + +JSON_TEST_DATA_PATH = pathlib.Path("tests/data/json/").resolve() + + +def clean(repo_path: str, repo: Optional[Repo]) -> None: + # Clean up the temporary Git repository + if repo is not None: + repo.close() + shutil.rmtree(repo_path) + + +def load_from_json( + tmp_trestle_dir: pathlib.Path, + file_prefix: str, + model_name: str, + model_type: OscalBaseModel, +) -> None: + """Load model from JSON test dir.""" + src_path = JSON_TEST_DATA_PATH / f"{file_prefix}.json" + dst_path: pathlib.Path = ModelUtils.get_model_path_for_name_and_class( + tmp_trestle_dir, model_name, model_type, FileContentType.JSON # type: ignore + ) + dst_path.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(src_path, dst_path) # type: ignore + + +def setup_for_ssp( + tmp_trestle_dir: pathlib.Path, prof_name: str, comp_name: str, output_name: str +) -> argparse.Namespace: + """Setup trestle temp directory for ssp testing""" + load_from_json(tmp_trestle_dir, comp_name, comp_name, comp.ComponentDefinition) # type: ignore + load_from_json(tmp_trestle_dir, prof_name, prof_name, prof.Profile) # type: ignore + load_from_json( + tmp_trestle_dir, + "simplified_nist_catalog", + "simplified_nist_catalog", + cat.Catalog, # type: ignore + ) + args = argparse.Namespace( + trestle_root=tmp_trestle_dir, + profile=prof_name, + compdefs=comp_name, + output=output_name, + verbose=0, + overwrite_header_values=False, + yaml_header=None, + allowed_sections=None, + force_overwrite=None, + ) + + return args + + +def setup_for_profile( + tmp_trestle_dir: pathlib.Path, prof_name: str, output_name: str +) -> argparse.Namespace: + """Setup trestle temp directory for profile testing.""" + load_from_json(tmp_trestle_dir, prof_name, prof_name, prof.Profile) # type: ignore + + load_from_json( + tmp_trestle_dir, + "simplified_nist_catalog", + "simplified_nist_catalog", + cat.Catalog, # type: ignore + ) + + args = argparse.Namespace( + trestle_root=tmp_trestle_dir, + name=prof_name, + output=output_name, + verbose=0, + yaml_header=None, + overwrite_header_values=False, + force_overwrite=None, + sections=None, + required_sections=None, + allowed_sections=None, + ) + + return args + + +def setup_for_catalog( + tmp_trestle_dir: pathlib.Path, cat_name: str, output_name: str +) -> argparse.Namespace: + """Setup trestle temp directory for catalog testing""" + load_from_json(tmp_trestle_dir, cat_name, cat_name, cat.Catalog) # type: ignore + args = argparse.Namespace( + trestle_root=tmp_trestle_dir, + name=cat_name, + output=output_name, + verbose=0, + overwrite_header_values=False, + yaml_header=None, + force_overwrite=None, + ) + + return args + + +def setup_for_compdef( + tmp_trestle_dir: pathlib.Path, comp_name: str, output_name: str +) -> argparse.Namespace: + """Setup trestle temp directory for component definitions testing""" + load_from_json(tmp_trestle_dir, comp_name, comp_name, comp.ComponentDefinition) # type: ignore + load_from_json( + tmp_trestle_dir, + "simplified_nist_profile", + "simplified_nist_profile", + prof.Profile, # type: ignore + ) + load_from_json( + tmp_trestle_dir, + "simplified_nist_catalog", + "simplified_nist_catalog", + cat.Catalog, # type: ignore + ) + args = argparse.Namespace( + trestle_root=tmp_trestle_dir, + name=comp_name, + output=output_name, + verbose=0, + yaml_header=None, + overwrite_header_values=False, + force_overwrite=None, + ) + + return args diff --git a/tests/trestlebot/__init__.py b/tests/trestlebot/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/trestlebot/tasks/__init__.py b/tests/trestlebot/tasks/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/trestlebot/tasks/authored/__init__.py b/tests/trestlebot/tasks/authored/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/trestlebot/tasks/authored/test_ssp.py b/tests/trestlebot/tasks/authored/test_ssp.py new file mode 100644 index 00000000..d31bee85 --- /dev/null +++ b/tests/trestlebot/tasks/authored/test_ssp.py @@ -0,0 +1,77 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Test for Trestle Bot Authored SSP.""" + +import pathlib +from typing import Dict + +import pytest +from trestle.common.model_utils import ModelUtils +from trestle.core.commands.author.ssp import SSPGenerate +from trestle.core.models.file_content_type import FileContentType +from trestle.oscal import ssp as ossp + +from tests import testutils +from trestlebot.tasks.authored.ssp import AuthoredSSP + + +test_prof = "simplified_nist_profile" +test_comp = "test_comp" +test_ssp_output = "test-ssp" +markdown_dir = "md_ssp" + + +def test_assemble(tmp_trestle_dir: str) -> None: + """Test to test assemble functionality for SSPs""" + # Prepare the workspace and generate the markdown + trestle_root = pathlib.Path(tmp_trestle_dir) + md_path = f"{markdown_dir}/{test_ssp_output}" + args = testutils.setup_for_ssp(trestle_root, test_prof, test_comp, md_path) + ssp_generate = SSPGenerate() + assert ssp_generate._run(args) == 0 + + comps_by_ssp: Dict[str, str] = {} + comps_by_ssp[test_ssp_output] = test_comp + + authored_ssp = AuthoredSSP(tmp_trestle_dir, comps_by_ssp) + + # Run to ensure no exceptions are raised + authored_ssp.assemble(md_path) + + # Check that the ssp is present in the correct location + ssp, _ = ModelUtils.load_model_for_class( + trestle_root, test_ssp_output, ossp.SystemSecurityPlan, FileContentType.JSON + ) + assert len(ssp.control_implementation.implemented_requirements) == 12 + + +def test_assemble_no_ssp_entry(tmp_trestle_dir: str) -> None: + """Test to test assemble functionality for SSPs""" + # Prepare the workspace and generate the markdown + trestle_root = pathlib.Path(tmp_trestle_dir) + md_path = f"{markdown_dir}/{test_ssp_output}" + args = testutils.setup_for_ssp(trestle_root, test_prof, test_comp, md_path) + ssp_generate = SSPGenerate() + assert ssp_generate._run(args) == 0 + + comps_by_ssp: Dict[str, str] = {} + comps_by_ssp["fake"] = test_comp + + authored_ssp = AuthoredSSP(tmp_trestle_dir, comps_by_ssp) + + with pytest.raises(ValueError): + authored_ssp.assemble(md_path) diff --git a/tests/trestlebot/tasks/test_assemble_task.py b/tests/trestlebot/tasks/test_assemble_task.py new file mode 100644 index 00000000..ab53bb50 --- /dev/null +++ b/tests/trestlebot/tasks/test_assemble_task.py @@ -0,0 +1,133 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Test for Trestle Bot assemble""" + +import os +import pathlib + +import pytest +from trestle.core.commands.author.catalog import CatalogGenerate +from trestle.core.commands.author.component import ComponentGenerate +from trestle.core.commands.author.profile import ProfileGenerate +from trestle.core.commands.author.ssp import SSPGenerate + +from tests import testutils +from trestlebot.tasks.assemble_task import AssembleTask +from trestlebot.tasks.authored.types import AuthoredType + + +test_prof = "simplified_nist_profile" +test_comp = "test_comp" +test_cat = "simplified_nist_catalog" +test_ssp_output = "my-ssp" + +cat_md_dir = "md_cat" +prof_md_dir = "md_prof" +compdef_md_dir = "md_comp" +ssp_md_dir = "md_ssp" + + +def test_catalog_assemble_task(tmp_trestle_dir: str) -> None: + """Test catalog assemble at the task level""" + trestle_root = pathlib.Path(tmp_trestle_dir) + md_path = os.path.join(cat_md_dir, test_cat) + args = testutils.setup_for_catalog(trestle_root, test_cat, md_path) + cat_generate = CatalogGenerate() + assert cat_generate._run(args) == 0 + + assemble_task = AssembleTask( + tmp_trestle_dir, + AuthoredType.CATALOG, + cat_md_dir, + "", + ) + assert assemble_task.execute() == 0 + + +def test_profile_assemble_task(tmp_trestle_dir: str) -> None: + """Test profile assemble at the task level""" + trestle_root = pathlib.Path(tmp_trestle_dir) + md_path = os.path.join(prof_md_dir, test_prof) + args = testutils.setup_for_profile(trestle_root, test_prof, md_path) + profile_generate = ProfileGenerate() + assert profile_generate._run(args) == 0 + assemble_task = AssembleTask( + tmp_trestle_dir, + AuthoredType.PROFILE, + prof_md_dir, + "", + ) + assert assemble_task.execute() == 0 + + +def test_compdef_assemble_task(tmp_trestle_dir: str) -> None: + """Test compdef assemble at the task level""" + trestle_root = pathlib.Path(tmp_trestle_dir) + md_path = os.path.join(compdef_md_dir, test_comp) + args = testutils.setup_for_compdef(trestle_root, test_comp, md_path) + comp_generate = ComponentGenerate() + assert comp_generate._run(args) == 0 + assemble_task = AssembleTask( + tmp_trestle_dir, + AuthoredType.COMPDEF, + compdef_md_dir, + "", + ) + assert assemble_task.execute() == 0 + + +def test_ssp_assemble_task(tmp_trestle_dir: str) -> None: + """Test ssp assemble at the task level""" + ssp_index_path = os.path.join(tmp_trestle_dir, "ssp-index.txt") + with open(ssp_index_path, "w") as f: + f.write(f"{test_ssp_output}:{test_comp}") + + trestle_root = pathlib.Path(tmp_trestle_dir) + md_path = os.path.join(ssp_md_dir, test_ssp_output) + args = testutils.setup_for_ssp(trestle_root, test_prof, test_comp, md_path) + ssp_generate = SSPGenerate() + assert ssp_generate._run(args) == 0 + + assemble_task = AssembleTask( + tmp_trestle_dir, + AuthoredType.SSP, + ssp_md_dir, + ssp_index_path, + ) + assert assemble_task.execute() == 0 + + +def test_ssp_assemble_task_no_index_path(tmp_trestle_dir: str) -> None: + """Test ssp assemble at the task level with failure""" + ssp_index_path = os.path.join(tmp_trestle_dir, "ssp-index.txt") + with open(ssp_index_path, "w") as f: + f.write(f"{test_ssp_output}:{test_comp}") + + trestle_root = pathlib.Path(tmp_trestle_dir) + md_path = os.path.join(ssp_md_dir, test_ssp_output) + args = testutils.setup_for_ssp(trestle_root, test_prof, test_comp, md_path) + ssp_generate = SSPGenerate() + assert ssp_generate._run(args) == 0 + + assemble_task = AssembleTask( + tmp_trestle_dir, + AuthoredType.SSP, + ssp_md_dir, + "", + ) + with pytest.raises(FileNotFoundError): + assemble_task.execute() diff --git a/tests/test_bot.py b/tests/trestlebot/test_bot.py similarity index 76% rename from tests/test_bot.py rename to tests/trestlebot/test_bot.py index fbcdc781..52bf0ce5 100644 --- a/tests/test_bot.py +++ b/tests/trestlebot/test_bot.py @@ -17,47 +17,19 @@ """Test for top-level Trestle Bot logic.""" import os -import shutil -import tempfile +from typing import Tuple -from git import Repo +from git.repo import Repo import trestlebot.bot as bot +from tests.testutils import clean -def repo_setup(repo_path: str) -> Repo: - repo = Repo.init(repo_path) - repo.config_writer().set_value("user", "name", "Test User").release() - repo.config_writer().set_value("user", "email", "test@example.com").release() - return repo - - -def create_tmp_directory(): - tmp_dir = tempfile.mkdtemp() - print(f"Temporary directory created: {tmp_dir}") - return tmp_dir - - -def clean(repo_path: str, repo: Repo): - # Clean up the temporary Git repository - if repo is not None: - repo.close() - shutil.rmtree(repo_path) - - -def test_stage_files(): - repo_path = create_tmp_directory() - repo = repo_setup(repo_path) - - # Create initial commit - file1_path = os.path.join(repo_path, "file1.txt") - with open(file1_path, "w") as f: - f.write("Test file 1 content initial") - repo.index.add(file1_path) - repo.index.commit("my test") +def test_stage_files(tmp_repo: Tuple[str, Repo]) -> None: + repo_path, repo = tmp_repo # Create test files - with open(file1_path, "w") as f: + with open(os.path.join(repo_path, "file1.txt"), "w") as f: f.write("Test file 1 content") with open(os.path.join(repo_path, "file2.txt"), "w") as f: f.write("Test file 2 content") @@ -75,9 +47,8 @@ def test_stage_files(): clean(repo_path, repo) -def test_local_commit(): - repo_path = create_tmp_directory() - repo = repo_setup(repo_path) +def test_local_commit(tmp_repo: Tuple[str, Repo]) -> None: + repo_path, repo = tmp_repo # Create a test file test_file_path = os.path.join(repo_path, "test.txt") @@ -106,9 +77,8 @@ def test_local_commit(): clean(repo_path, repo) -def test_local_commit_with_committer(): - repo_path = create_tmp_directory() - repo = repo_setup(repo_path) +def test_local_commit_with_committer(tmp_repo: Tuple[str, Repo]) -> None: + repo_path, repo = tmp_repo # Create a test file test_file_path = os.path.join(repo_path, "test.txt") @@ -137,9 +107,8 @@ def test_local_commit_with_committer(): clean(repo_path, repo) -def test_local_commit_with_author(): - repo_path = create_tmp_directory() - repo = repo_setup(repo_path) +def test_local_commit_with_author(tmp_repo: Tuple[str, Repo]) -> None: + repo_path, repo = tmp_repo # Create a test file test_file_path = os.path.join(repo_path, "test.txt") @@ -170,9 +139,8 @@ def test_local_commit_with_author(): clean(repo_path, repo) -def test_run_dry_run(): - repo_path = create_tmp_directory() - repo = repo_setup(repo_path) +def test_run_dry_run(tmp_repo: Tuple[str, Repo]) -> None: + repo_path, repo = tmp_repo # Create a test file test_file_path = os.path.join(repo_path, "test.txt") diff --git a/trestlebot/bot.py b/trestlebot/bot.py index a0315933..1bd109c1 100644 --- a/trestlebot/bot.py +++ b/trestlebot/bot.py @@ -20,7 +20,11 @@ import sys from typing import List, Optional -from git import Actor, GitCommandError, Repo +from git import GitCommandError +from git.repo import Repo +from git.util import Actor + +from trestlebot.tasks.base_task import TaskBase, TaskException logging.basicConfig( @@ -34,7 +38,7 @@ class RepoException(Exception): """ -def _stage_files(gitwd: Repo, patterns: List[str]): +def _stage_files(gitwd: Repo, patterns: List[str]) -> None: """Stages files in git based on file patterns""" for pattern in patterns: logging.info(f"Adding file for pattern {pattern}") @@ -48,7 +52,7 @@ def _local_commit( commit_message: str, author_name: str = "", author_email: str = "", -): +) -> None: """Creates a local commit in git working directory""" try: # Set the user and email for the commit @@ -75,9 +79,18 @@ def run( author_name: str, author_email: str, patterns: List[str], + pre_tasks: Optional[List[TaskBase]] = None, dry_run: bool = False, -) -> bool: - """Run Trestle Bot.""" +) -> int: + """Run Trestle Bot and return exit code""" + + # Execute bot pre-tasks before committing repository updates + if pre_tasks is not None: + for task in pre_tasks: + try: + task.execute() + except TaskException as e: + raise RepoException(f"Bot pre-tasks failed: {e}") # Create Git Repo repo = Repo(working_dir) @@ -98,7 +111,7 @@ def run( if dry_run: logging.info("Dry run mode is enabled. Do not push to remote.") - return True + return 0 try: # Get the remote repository by name @@ -108,13 +121,13 @@ def run( remote.push(refspec=f"HEAD:{branch}") logging.info(f"Changes pushed to {branch} successfully.") - return True + return 0 except GitCommandError as e: raise RepoException(f"Git push to {branch} failed: {e}") from e else: logging.info("Nothing to commit") - return True + return 0 else: logging.info("Nothing to commit") - return True + return 0 diff --git a/trestlebot/cli.py b/trestlebot/cli.py index db0dcaa6..9dea7aca 100644 --- a/trestlebot/cli.py +++ b/trestlebot/cli.py @@ -18,9 +18,19 @@ """This module parses CLI arguments for the Trestle Bot.""" import argparse +import logging import sys +from typing import List from trestlebot import bot +from trestlebot.tasks.assemble_task import AssembleTask +from trestlebot.tasks.authored import types +from trestlebot.tasks.base_task import TaskBase + + +logging.basicConfig( + format="%(levelname)s - %(message)s", stream=sys.stdout, level=logging.INFO +) def _parse_cli_arguments() -> argparse.Namespace: @@ -33,6 +43,18 @@ def _parse_cli_arguments() -> argparse.Namespace: required=True, help="Branch name to push changes to", ) + parser.add_argument( + "--markdown-path", + required=True, + type=str, + help="Path to Trestle markdown files", + ) + parser.add_argument( + "--assemble-model", + required=True, + type=str, + help="OSCAL Model type to assemble. Values can be catalog, profile, compdef, or ssp", + ) parser.add_argument( "--working-dir", type=str, @@ -40,6 +62,13 @@ def _parse_cli_arguments() -> argparse.Namespace: default=".", help="Working directory wit git repository", ) + parser.add_argument( + "--commit-message", + type=str, + required=False, + default="chore: automatic updates", + help="Commit message for automated updates", + ) parser.add_argument( "--committer-name", type=str, @@ -67,25 +96,65 @@ def _parse_cli_arguments() -> argparse.Namespace: help="Email for commit author if differs from committer", ) parser.add_argument( - "--patterns", nargs="+", type=str, required=True, help="List of file patterns" + "--ssp-index-path", + required=False, + type=str, + default="ssp-index.txt", + help="Path to ssp index file", + ) + parser.add_argument( + "--patterns", + nargs="+", + type=str, + required=True, + help="List of file patterns to include in repository updates", ) return parser.parse_args() -def run(): +def run() -> None: """Trestle Bot entry point function.""" args = _parse_cli_arguments() - success = bot.run( + pre_tasks: List[TaskBase] = [] + + # Pre-process flags + if args.assemble_model: + assembled_type: types.AuthoredType + try: + assembled_type = types.check_authored_type(args.assembled_model) + except ValueError: + logging.error( + f"Invalid value {args.assemble_model} for assemble model. \ + Please use catalog, profile, compdef, or ssp." + ) + sys.exit(1) + + if not args.markdown_path: + logging.error("Must set markdown path with assemble model.") + sys.exit(1) + + if args.assemble_model == "ssp" & args.ssp_index_path == "": + logging.error("Must set ssp_index_path when using SSP as assemble model.") + sys.exit(1) + + assemble_task = AssembleTask( + args.working_dir, + assembled_type, + args.markdown_dir, + args.ssp_index_path, + ) + pre_tasks.append(assemble_task) + + exit_code = bot.run( working_dir=args.working_dir, branch=args.branch, commit_name=args.committer_name, commit_email=args.committer_email, + commit_message=args.commit_message, author_name=args.author_name, author_email=args.author_email, + pre_tasks=pre_tasks, patterns=args.patterns, ) - if success: - sys.exit(0) - else: - sys.exit(1) + sys.exit(exit_code) diff --git a/trestlebot/tasks/__init__.py b/trestlebot/tasks/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/trestlebot/tasks/assemble_task.py b/trestlebot/tasks/assemble_task.py new file mode 100644 index 00000000..014b0b4e --- /dev/null +++ b/trestlebot/tasks/assemble_task.py @@ -0,0 +1,99 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Trestle Bot Assembly Tasks""" + +import os +from typing import Dict + +from trestlebot.tasks.authored import types +from trestlebot.tasks.authored.base_authored import ( + AuthoredObjectException, + AuthorObjectBase, +) +from trestlebot.tasks.authored.catalog import AuthoredCatalog +from trestlebot.tasks.authored.compdef import AuthoredComponentsDefinition +from trestlebot.tasks.authored.profile import AuthoredProfile +from trestlebot.tasks.authored.ssp import AuthoredSSP +from trestlebot.tasks.base_task import TaskBase, TaskException + + +class AssembleTask(TaskBase): + """ + Assemble Markdown into OSCAL content + """ + + def __init__( + self, + working_dir: str, + authored_model: types.AuthoredType, + markdown_dir: str, + ssp_index_path: str = "", + ) -> None: + """ + Initialize assemble task. + + Args: + working_dir: Working directory to complete operations in. + authored_model: Model type . + markdown_dir: Working directory to complete operations in. + ssp_index_path: + + """ + + self._authored_model = authored_model + self._markdown_dir = markdown_dir + self._ssp_index_path = ssp_index_path + super().__init__(working_dir) + + def execute(self) -> int: + """Execute task""" + return self._assemble() + + def _assemble(self) -> int: + """Assemble all objects in markdown directory""" + authored_object: AuthorObjectBase = self._get_authored_object() + search_path = os.path.join(self._working_dir, self._markdown_dir) + for model in os.listdir(search_path): + # Construct model path from markdown. AuthoredObject already + # have the working dir data. + model_path = os.path.join(self._markdown_dir, model) + try: + authored_object.assemble(model_path=model_path) + except AuthoredObjectException as e: + raise TaskException(f"Assemble task failed for model {model_path}: {e}") + return 0 + + def _get_authored_object(self) -> AuthorObjectBase: + """Determine and configure author object context""" + if self._authored_model is types.AuthoredType.CATALOG: # noqa: E721 + return AuthoredCatalog(self._working_dir) + elif self._authored_model is types.AuthoredType.PROFILE: # noqa: E721 + return AuthoredProfile(self._working_dir) + elif self._authored_model is types.AuthoredType.COMPDEF: # noqa: E721 + return AuthoredComponentsDefinition(self._working_dir) + elif self._authored_model is types.AuthoredType.SSP: # noqa: E721 + comps_by_ssp: Dict[str, str] = {} + + with open(self._ssp_index_path, "r") as file: + for line in file: + line = line.strip() + if line: + key, value = line.split(":", 1) + comps_by_ssp[key] = value + return AuthoredSSP(self._working_dir, comps_by_ssp) + else: + raise TaskException(f"Invalid authored type {self._authored_model}") diff --git a/trestlebot/tasks/authored/__init__.py b/trestlebot/tasks/authored/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/trestlebot/tasks/authored/base_authored.py b/trestlebot/tasks/authored/base_authored.py new file mode 100644 index 00000000..7892d561 --- /dev/null +++ b/trestlebot/tasks/authored/base_authored.py @@ -0,0 +1,37 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Trestle Bot base authored object""" + +from abc import ABC, abstractmethod + + +class AuthoredObjectException(Exception): + """An error during object authoring""" + + +class AuthorObjectBase(ABC): + """ + Abstract base class for OSCAL objects that are authored. + """ + + def __init__(self, trestle_root: str) -> None: + """Initialize task base and store trestle root path""" + self._trestle_root = trestle_root + + @abstractmethod + def assemble(self, model_path: str, version_tag: str = "") -> None: + """Execute assemble for model path""" diff --git a/trestlebot/tasks/authored/catalog.py b/trestlebot/tasks/authored/catalog.py new file mode 100644 index 00000000..70311b88 --- /dev/null +++ b/trestlebot/tasks/authored/catalog.py @@ -0,0 +1,68 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Trestle Bot functions for catalog authoring""" + +import logging +import os +import pathlib +import sys + +from trestle.common.err import TrestleError +from trestle.core.commands.author.catalog import CatalogAssemble +from trestle.core.commands.common.return_codes import CmdReturnCodes + +from trestlebot.tasks.authored.base_authored import ( + AuthoredObjectException, + AuthorObjectBase, +) + + +logging.basicConfig( + format="%(levelname)s - %(message)s", stream=sys.stdout, level=logging.INFO +) + + +class AuthoredCatalog(AuthorObjectBase): + """ + Functions for authoring OSCAL catalogs in automation + """ + + def __init__(self, trestle_root: str) -> None: + """ + Initialize authored catalog. + """ + super().__init__(trestle_root) + + def assemble(self, model_path: str, version_tag: str = "") -> None: + trestle_root = pathlib.Path(self._trestle_root) + catalog = os.path.basename(model_path) + try: + exit_code = CatalogAssemble.assemble_catalog( + trestle_root=trestle_root, + md_name=model_path, + assem_cat_name=catalog, + parent_cat_name="", + set_parameters_flag=True, + regenerate=False, + version=version_tag, + ) + if exit_code != CmdReturnCodes.SUCCESS.value: + raise AuthoredObjectException( + f"Unknown error occurred while assembling {catalog}" + ) + except TrestleError as e: + raise AuthoredObjectException(f"Trestle assemble failed for {catalog}: {e}") diff --git a/trestlebot/tasks/authored/compdef.py b/trestlebot/tasks/authored/compdef.py new file mode 100644 index 00000000..3284ba40 --- /dev/null +++ b/trestlebot/tasks/authored/compdef.py @@ -0,0 +1,67 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Trestle Bot functions for component definition authoring""" + +import logging +import os +import pathlib +import sys + +from trestle.common.err import TrestleError +from trestle.core.commands.author.component import ComponentAssemble +from trestle.core.commands.common.return_codes import CmdReturnCodes + +from trestlebot.tasks.authored.base_authored import ( + AuthoredObjectException, + AuthorObjectBase, +) + + +logging.basicConfig( + format="%(levelname)s - %(message)s", stream=sys.stdout, level=logging.INFO +) + + +class AuthoredComponentsDefinition(AuthorObjectBase): + """ + Functions for authoring OSCAL Component Definitions in automation + """ + + def __init__(self, trestle_root: str) -> None: + """ + Initialize authored component definitions object. + """ + super().__init__(trestle_root) + + def assemble(self, model_path: str, version_tag: str = "") -> None: + trestle_root = pathlib.Path(self._trestle_root) + compdef = os.path.basename(model_path) + try: + exit_code = ComponentAssemble.assemble_component( + trestle_root=trestle_root, + md_name=model_path, + assem_comp_name=compdef, + parent_comp_name="", + regenerate=False, + version=version_tag, + ) + if exit_code != CmdReturnCodes.SUCCESS.value: + raise AuthoredObjectException( + f"Unknown error occurred while assembling {compdef}" + ) + except TrestleError as e: + raise AuthoredObjectException(f"Trestle assemble failed for {compdef}: {e}") diff --git a/trestlebot/tasks/authored/profile.py b/trestlebot/tasks/authored/profile.py new file mode 100644 index 00000000..fad96f74 --- /dev/null +++ b/trestlebot/tasks/authored/profile.py @@ -0,0 +1,71 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Trestle Bot functions for profile authoring""" + +import logging +import os +import pathlib +import sys + +from trestle.common.err import TrestleError +from trestle.core.commands.author.profile import ProfileAssemble +from trestle.core.commands.common.return_codes import CmdReturnCodes + +from trestlebot.tasks.authored.base_authored import ( + AuthoredObjectException, + AuthorObjectBase, +) + + +logging.basicConfig( + format="%(levelname)s - %(message)s", stream=sys.stdout, level=logging.INFO +) + + +class AuthoredProfile(AuthorObjectBase): + """ + Functions for authoring OSCAL Profiles in automation + """ + + def __init__(self, trestle_root: str) -> None: + """ + Initialize authored profiles object. + """ + super().__init__(trestle_root) + + def assemble(self, model_path: str, version_tag: str = "") -> None: + trestle_root = pathlib.Path(self._trestle_root) + profile = os.path.basename(model_path) + try: + exit_code = ProfileAssemble.assemble_profile( + trestle_root=trestle_root, + md_name=model_path, + assem_prof_name=profile, + parent_prof_name="", + set_parameters_flag=True, + regenerate=False, + version=version_tag, + allowed_sections=None, + required_sections=[], + sections_dict={}, + ) + if exit_code != CmdReturnCodes.SUCCESS.value: + raise AuthoredObjectException( + f"Unknown error occurred while assembling {profile}" + ) + except TrestleError as e: + raise AuthoredObjectException(f"Trestle assemble failed for {profile}: {e}") diff --git a/trestlebot/tasks/authored/ssp.py b/trestlebot/tasks/authored/ssp.py new file mode 100644 index 00000000..3406c145 --- /dev/null +++ b/trestlebot/tasks/authored/ssp.py @@ -0,0 +1,79 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Trestle Bot functions for SSP authoring""" + +import argparse +import logging +import os +import sys +from typing import Dict + +from trestle.common.err import TrestleError +from trestle.core.commands.author.ssp import SSPAssemble +from trestle.core.commands.common.return_codes import CmdReturnCodes + +from trestlebot.tasks.authored.base_authored import ( + AuthoredObjectException, + AuthorObjectBase, +) + + +logging.basicConfig( + format="%(levelname)s - %(message)s", stream=sys.stdout, level=logging.INFO +) + + +class AuthoredSSP(AuthorObjectBase): + """ + Functions for authoring OSCAL SSPs in automation + """ + + def __init__(self, trestle_root: str, comps_by_ssp: Dict[str, str]) -> None: + """ + Initialize authored ssps object. + """ + super().__init__(trestle_root) + self.comps_by_ssp = comps_by_ssp + + def assemble(self, model_path: str, version_tag: str = "") -> None: + ssp_assemble: SSPAssemble = SSPAssemble() + ssp = os.path.basename(model_path) + + try: + comps = self.comps_by_ssp[ssp] + except KeyError: + raise ValueError(f"{ssp} not in ssp index") + + try: + args = argparse.Namespace( + trestle_root=self._trestle_root, + markdown=model_path, + output=ssp, + verbose=0, + regenerate=False, + version=version_tag, + name=None, + compdefs=comps, + ) + + exit_code = ssp_assemble._run(args) + if exit_code != CmdReturnCodes.SUCCESS.value: + raise AuthoredObjectException( + f"Unknown error occurred while assembling {ssp}" + ) + except TrestleError as e: + raise AuthoredObjectException(f"Trestle assemble failed for {ssp}: {e}") diff --git a/trestlebot/tasks/authored/types.py b/trestlebot/tasks/authored/types.py new file mode 100644 index 00000000..0d6eddb7 --- /dev/null +++ b/trestlebot/tasks/authored/types.py @@ -0,0 +1,37 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Trestle Bot constants""" + +from enum import Enum + + +class AuthoredType(Enum): + """Top-level OSCAL models that have authoring support""" + + CATALOG = "catalog" + PROFILE = "profile" + SSP = "ssp" + COMPDEF = "compdef" + + +def check_authored_type(input_type: str) -> AuthoredType: + """Check if the string has a matching AuthoredType, if not raise an error""" + try: + item_type = AuthoredType[input_type.upper()] + return item_type + except KeyError: + raise ValueError(f"Invalid item type: {input_type}") diff --git a/trestlebot/tasks/base_task.py b/trestlebot/tasks/base_task.py new file mode 100644 index 00000000..df39ef31 --- /dev/null +++ b/trestlebot/tasks/base_task.py @@ -0,0 +1,49 @@ +#!/usr/bin/python + +# Copyright 2023 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Trestle Bot base task for extendable bot pre-tasks""" + +from abc import ABC, abstractmethod + + +# TODO: Incorporate a configuration file for model specific tasks + + +class TaskException(Exception): + """An error during task execution""" + + +class TaskBase(ABC): + """ + Abstract base class for tasks with a work directory. + """ + + def __init__(self, working_dir: str) -> None: + """ + Initialize base task. + + Args: + working_dir: Working directory to complete operations in. + """ + self._working_dir = working_dir + + def get_working_dir(self) -> str: + """Return the working directory""" + return self._working_dir + + @abstractmethod + def execute(self) -> int: + """Execute the task and return the exit code"""