{"id":17298995,"url":"https://github.com/egibs/python-fips","last_synced_at":"2026-03-08T05:33:09.696Z","repository":{"id":217234713,"uuid":"743344883","full_name":"egibs/python-fips","owner":"egibs","description":"Dockerfile(s) for experiementing with Python x FIPS","archived":false,"fork":false,"pushed_at":"2024-07-29T18:18:45.000Z","size":91,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-29T08:40:54.985Z","etag":null,"topics":["docker","fips","fips-140-2","fips-build","openssl","python","python3","python311","python312","python39"],"latest_commit_sha":null,"homepage":"","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/egibs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-15T02:48:15.000Z","updated_at":"2025-01-27T05:30:54.000Z","dependencies_parsed_at":"2024-01-15T06:49:09.743Z","dependency_job_id":"3138a841-1cbb-47aa-89fb-3972477a0922","html_url":"https://github.com/egibs/python-fips","commit_stats":null,"previous_names":["egibs/python-fips"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/egibs/python-fips","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egibs%2Fpython-fips","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egibs%2Fpython-fips/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egibs%2Fpython-fips/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egibs%2Fpython-fips/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/egibs","download_url":"https://codeload.github.com/egibs/python-fips/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egibs%2Fpython-fips/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30246730,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T00:58:18.660Z","status":"online","status_checked_at":"2026-03-08T02:00:06.215Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","fips","fips-140-2","fips-build","openssl","python","python3","python311","python312","python39"],"created_at":"2024-10-15T11:20:42.714Z","updated_at":"2026-03-08T05:33:04.673Z","avatar_url":"https://github.com/egibs.png","language":"Dockerfile","readme":"# python-fips\n\nDockerfile(s) for experiementing with Python x FIPS\n\n## Getting started\n\nBuild any of the supported Dockerfiles via their respective Makefile targets.\n\n### Support Matrix\n\n| Python Version | Linux Distribution | OpenSSL Version | Architecture\n| --- | --- | --- | --- |\n| `3.9.19` | Rocky 9 | `1.0.2u` (Base) \u003c/br\u003e `2.0.16` (FIPS provider) | `linux/amd64`\n| `3.9.19` | Wolfi | `1.0.2.u` (Base) \u003c/br\u003e `2.0.16` (FIPS provider) | `linux/amd64`\n| `3.11.9` | Rocky 9 | `3.0.9` | `linux/amd64` \u003c/br\u003e `linux/arm64`\n| `3.11.9` | Wolfi | `3.0.9` | `linux/amd64` \u003c/br\u003e `linux/arm64`\n| `3.12.3` | Rocky 9 | `3.0.9` | `linux/amd64` \u003c/br\u003e `linux/arm64`\n| `3.12.3` | Wolfi | `3.0.9` | `linux/amd64` \u003c/br\u003e `linux/arm64`\n\n\u003e OpenSSL `3.0.9` is the latest FIPS-approved version of OpenSSL; while it is possible to use the latest OpenSSL release and use `3.0.9` to handle the FIPS provider portion, it's not approved or supported.\n\nTo build the image, either run `make build` or run the full `docker buildx build` command, e.g.:\n```sh\ndocker buildx build -f Dockerfile-3.11.wolfi . -t python-fips-wolfi-3.11:latest\n```\n\n\u003e For the `3.9` images, using `linux/amd64` is recommended since ARM64 is most likely unsupported from a FIPS-standpoint (TBD, though).\n\n\nThe image is comprised of two stages:\n\n1. `patch`\n2. `primary/build`\n\nThe `patch` stage downloads the Python archive and applies the contents of `fips.patch` to the necessary files. The Python code is copied over into the primary stage where it is built after OpenSSL.\n\n## Contents\n\nThe contents of the Dockerfile are minimal -- only the packages and dependencies needed to build OpenSSL and Python are included.\n\nThe `patch` stage installs the following:\n\n- `patchutils` (Rocky); `patch` (Wolfi)\n- `wget`\n\nThen downloads the versioned Python Archive and patches various Python source files depending on the Python release and the contents of the `fips_*.patch` files.\n\nThe primary stage installs the following on the Rocky variants:\n- `autoconf`\n- `automake`\n- `bzip2-devel`\n- `diffutils`\n- `gcc`\n- `libffi`\n- `libffi-devel`\n- `libjpeg-devel`\n- `libssh-devel`\n- `libtool`\n- `libxml2-devel`\n- `libxslt-devel`\n- `make`\n- `perl`\n- `wget`\n- `zlib-devel`\n\nand the following on the Wolfi variants:\n- `autoconf`\n- `automake`\n- `bzip2-dev`\n- `diffutils`\n- `gcc`\n- `glibc`\n- `glibc-dev`\n- `ld-linux`\n- `libffi`\n- `libffi-dev`\n- `libjpeg-dev`\n- `libssh-dev`\n- `libtool`\n- `libxml2-dev`\n- `libxslt-dev`\n- `make`\n- `perl`\n- `wgets`\n- `zlib-dev`\n\nThen downloads the OpenSSL archives (both the FIPS module and primary release) and builds both OpenSSL and Python before finishing up with an installation of a specific version of `cryptography`.\n\n## Usage\n\n### Python3.9\n\nAfter the image is built, start a container and test it out:\n\n```sh\n❯ docker run --rm -it --entrypoint bash python-fips:latest\nWARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested\nbash-5.1# python3\nPython 3.9.18 (main, Jan 15 2024, 02:39:33)\n[GCC 11.4.1 20230605 (Red Hat 11.4.1-2)] on linux\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\u003e\u003e\u003e import ssl\n\u003e\u003e\u003e ssl.OPENSSL_VERSION\n'OpenSSL 1.0.2u-fips  20 Dec 2019'\n\u003e\u003e\u003e ssl.FIPS_mode()\n0\n\u003e\u003e\u003e ssl.FIPS_mode_set(1)\n\u003e\u003e\u003e ssl.FIPS_mode()\n1\n```\n\n### Python3.11 and Python3.12\n\nThe output for the newer Python and OpenSSL versions is a little messier since FIPS is handled differently, but the important part is this:\n```\n\u003e\u003e hashlib.new(\"sha256\")\n\u003csha256 _hashlib.HASH object @ 0xffffa117be10\u003e\n\u003e\u003e\u003e hashlib.new(\"md5\")\nTraceback (most recent call last):\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 165, in __hash_new\n    return _hashlib.new(name, data, **kwargs)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n_hashlib.UnsupportedDigestmodError: [digital envelope routines] unsupported\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 171, in __hash_new\n    return __get_builtin_constructor(name)(data)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 87, in __get_builtin_constructor\n    raise ValueError('unsupported hash type ' + name + '(in FIPS mode)')\nValueError: unsupported hash type md5(in FIPS mode)\n```\n\n`md5` and `blake2*` are not supported under FIPS.\n\n```sh\na0817bb0b9e3:/# python3\nPython 3.12.3 (main, Apr 28 2024, 23:05:04) [GCC 13.2.0] on linux\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\u003e\u003e\u003e import ssl\n\u003e\u003e\u003e ssl.OPENSSL_VERSION\n'OpenSSL 3.0.9 30 May 2023'\n\u003e\u003e\u003e import hashlib\nERROR:root:code for hash md5 was not found.\nTraceback (most recent call last):\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 142, in __get_openssl_constructor\n    f(usedforsecurity=False)\n_hashlib.UnsupportedDigestmodError: [digital envelope routines] unsupported\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 250, in \u003cmodule\u003e\n    globals()[__func_name] = __get_hash(__func_name)\n                             ^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 146, in __get_openssl_constructor\n    return __get_builtin_constructor(name)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 87, in __get_builtin_constructor\n    raise ValueError('unsupported hash type ' + name + '(in FIPS mode)')\nValueError: unsupported hash type md5(in FIPS mode)\nERROR:root:code for hash blake2b was not found.\nTraceback (most recent call last):\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 142, in __get_openssl_constructor\n    f(usedforsecurity=False)\n_hashlib.UnsupportedDigestmodError: [digital envelope routines] unsupported\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 250, in \u003cmodule\u003e\n    globals()[__func_name] = __get_hash(__func_name)\n                             ^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 146, in __get_openssl_constructor\n    return __get_builtin_constructor(name)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 87, in __get_builtin_constructor\n    raise ValueError('unsupported hash type ' + name + '(in FIPS mode)')\nValueError: unsupported hash type blake2b(in FIPS mode)\nERROR:root:code for hash blake2s was not found.\nTraceback (most recent call last):\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 142, in __get_openssl_constructor\n    f(usedforsecurity=False)\n_hashlib.UnsupportedDigestmodError: [digital envelope routines] unsupported\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 250, in \u003cmodule\u003e\n    globals()[__func_name] = __get_hash(__func_name)\n                             ^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 146, in __get_openssl_constructor\n    return __get_builtin_constructor(name)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 87, in __get_builtin_constructor\n    raise ValueError('unsupported hash type ' + name + '(in FIPS mode)')\nValueError: unsupported hash type blake2s(in FIPS mode)\n\u003e\u003e\u003e hashlib.new(\"sha256\")\n\u003csha256 _hashlib.HASH object @ 0xffffa117be10\u003e\n\u003e\u003e\u003e hashlib.new(\"md5\")\nTraceback (most recent call last):\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 165, in __hash_new\n    return _hashlib.new(name, data, **kwargs)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n_hashlib.UnsupportedDigestmodError: [digital envelope routines] unsupported\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 171, in __hash_new\n    return __get_builtin_constructor(name)(data)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/opt/python-fips/lib/python3.12/hashlib.py\", line 87, in __get_builtin_constructor\n    raise ValueError('unsupported hash type ' + name + '(in FIPS mode)')\nValueError: unsupported hash type md5(in FIPS mode)\n```\n\n## Troubleshooting\n\nBuilding Python with a specifc OpenSSL version can be pretty tedious.\n\nIf building OpenSSL using `--prefix=/some/path`, ensure that the Python build reflects this by adding `--with-openssl=/some/path/openssl` to the `configure` step.\n\nAlso, adding `-Wl,-rpath=/opt/python-fips/lib` to `LDFLAGS` during the Python `./configure` step along with `echo \"/opt/python-fips/lib\" \u003e /etc/ld.so.conf.d/python.conf` + `ldconfig -v` can resolve some library issues (and even enable the correct detection of the new Python installation).\n\nMore discussing on this can be found here:\n\n- https://stackoverflow.com/a/38781440\n\nWhen building OpenSSL 3.x, specifying both `--prefix` and `--openssldir` is recommended so that the `\u003c1.1.0` behavior is more or less replicated.\n\nMore on this can be found here:\n- https://wiki.openssl.org/index.php/Compilation_and_Installation\n\nThe most common issue I ran into while building this Dockerfile (which was much harder than doing locally in a VM, even in WSL2 or in EC2) was that Python would build against the wrong OpenSSL version or the Python installation would not be the correct one (i.e., the system Python -- even when overwriting it or using `make altinstall`).\n\nThe configuration in the `Dockerfile` works and can serve as a starting point for other implementations.\n\nSomething to note: the feedback loop for doing cross-arch builds on an M1 Mac is very slow (25-30 minutes E2E). For troubleshooting, starting a container that has already been built and trying new/different commands is faster than building from scratch each time. This is especially useful if OpenSSL has been installed correctly but Python isn't building as expected.\n\n## Acknowledgements\n\nHuge shoutout to GyanBlog for the following posts that inspired this work and made the process much less painful (even though it was still fairly arduous):\n\n- https://www.gyanblog.com/security/dockerfile-fips-enabled-python-with-openssl/\n- https://www.gyanblog.com/security/how-build-patch-python-3.9.x-fips-enable/\n- https://www.gyanblog.com/security/how-build-patch-python-3.7.9-fips-enable/\n\nThe 3.9 patch code is also c/o GyanBlog -- I only made a few tweaks to the file paths in the file so that `patch` could find them automatically inside of the extracted Python directory without needing manual intervention.\n\nUpstream Python3.11/3.12 patches can be found here:\n- https://gitlab.com/redhat/centos-stream/rpms/python3.11/-/blob/c8s/00329-fips.patch?ref_type=heads\n- https://gitlab.com/redhat/centos-stream/rpms/python3.12/-/blob/c8s/00329-fips.patch?ref_type=heads\n\nThis repo made small tweaks to `Lib/py_compile.py` in the 3.11 patch and `Lib/hmac.py` in the 3.12 patch, respectively. The patching process would not succeed otherwise.\n\n## TODO\n\nThe Dockerfiles are fairly clean but can be optimized further.\n\nThe idea for using a Docker image is that it can be used for Lambdas or as a way to pull out the built Python binary (TBD how well that works, though).\n\nThat said, it's also way more reproducible than spinning up EC2 instances and doing this manually (though an AMI made via Packer would get around this).\n\n## Why?\n\nJust to see if I could, really. \n\nThis is a very heavy process and not at all recommended if you can avoid it. The wonderful folks at Chainguard have FIPS variants of their Python images if you _really_ need this.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegibs%2Fpython-fips","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fegibs%2Fpython-fips","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegibs%2Fpython-fips/lists"}