{"id":15887841,"url":"https://github.com/ornl/certified","last_synced_at":"2026-03-04T04:31:30.176Z","repository":{"id":257807450,"uuid":"864290039","full_name":"ORNL/certified","owner":"ORNL","description":"The missing certificate infrastructure for web APIs.","archived":false,"fork":false,"pushed_at":"2024-11-08T04:44:21.000Z","size":410,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-16T15:49:14.553Z","etag":null,"topics":["fastapi","microservices","x509"],"latest_commit_sha":null,"homepage":"https://certified.readthedocs.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ORNL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-09-27T21:36:40.000Z","updated_at":"2024-10-17T06:36:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"059e1d37-e6d7-4769-8ba8-4420c175fc64","html_url":"https://github.com/ORNL/certified","commit_stats":null,"previous_names":["ornl/certified"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ORNL%2Fcertified","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ORNL%2Fcertified/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ORNL%2Fcertified/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ORNL%2Fcertified/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ORNL","download_url":"https://codeload.github.com/ORNL/certified/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244126791,"owners_count":20402178,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["fastapi","microservices","x509"],"created_at":"2024-10-06T06:05:18.072Z","updated_at":"2026-03-04T04:31:30.135Z","avatar_url":"https://github.com/ORNL.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CI](https://github.com/ORNL/certified/actions/workflows/python-package.yml/badge.svg)](https://github.com/ORNL/certified/actions)\n[![Docs](https://readthedocs.org/projects/certified/badge/)](https://certified.readthedocs.io)\n[![Coverage](https://codecov.io/github/ORNL/certified/branch/main/graph/badge.svg)](https://app.codecov.io/gh/ORNL/certified)\n\n\n# Certified\n\nAn idiomatic framework for using certificates\nand cookies (macaroons/biscuits) within python web API-s.\n\nWe make the following design choices:\n\n* mTLS - mutual transport layer certificates (x509) authenticate\n  client and server to one another\n\n* scopes - clients can \"prove\" they have access to a scope\n  (e.g. admin) by including it within their 'certificatePolicies'\n  *at the handshake* phase\n\n* tokens/cookies - we rely on the [datalog model of biscuits](https://doc.biscuitsec.org/reference/datalog)\n  to exchange cookies that carry authorization proofs.\n  Tokens, not certificates are used to delegate authorization.\n\n* symmetry - symmetric ideas are used for setting up\n  mutual identity verification (authentication) between\n  client and server.  This allows servers to act as clients\n  in complex workflows, and clients to act as servers\n  to run callbacks.\n\n* key management - we prescribe a file layout for these.\n  Key file-names serve as a short-hand for referencing a\n  given client/server.  See [docs/keys](docs/keys.md).\n\n\n---\n\nHow do I know who originated an API request -- what organization\nthey come from, and what kinds of organizational policies they have\nbeen asked to follow?\n\nHow can I consistently apply my own site's security policy\nto API actions?\n\nAnd -- the big question -- how can I, as a client using an API,\nobtain, manage, and send these credentials to servers I interact\nwith?\n\nThe certified package has you covered.\n\n\nSee [documentation](docs) for explanations and howto-s.\n\n# License\n\nCertified is available under a 3-clause BSD-style license,\navailable in the file LICENSE.\n\nPortions of certified (as marked in the code) are derived\nfrom [python-trio/trustme](https://github.com/python-trio/trustme),\nand are made available under the MIT license\n-- as reproduced within those files.\n\n# Installation\n\nAs a user, install with\n\n    pip install .\n\n## For development\n\nAs a developer, install with:\n\n    make install\n\nAdd new dependencies using, e.g.:\n\n    uv add pydantic          # run-time dependency\n    uv add --optional docs mkdocs-material # documentation-generation dep.\n    uv add --dev mypy        # development dependency\n\nRun tests with:\n\n    uv run mypy .\n    uv run pytest\n\nPreview the documentation with:\n\n    uv run mkdocs serve \u0026\n\n# Docs\n\nDocumentation was built using [this guide](https://realpython.com/python-project-documentation-with-mkdocs/) -- which comes highly recommended.\n\n# Roadmap\n\n* v0.8.1\n\n  - [x] use base64-encoded DER for storing keys in yaml files.\n\n  - [x] select certificate chain to send to server based on\n    server name (test server configs.)\n\n* v0.9.0\n\n  - [X] better logging\n\n  - [X] simpler introduction methodology\n\n  - [X] readthedocs integration\n\n  - [X] biscuit examples\n\n* v0.10.0\n\n  - [X] more feature-ful 'message' function\n\n  - [X] add docs on how to use openssl to decode certificate contents\n\n  - [X] configurable `biscuit_sec.Authorizor`-based biscuit auth\n\n  - [X] better user experience with add-intro (now adds services)\n\n  - [X] better user experience with add-service (will look for json with `ca_cert`)\n\n  - [X] better user experience setting up org-level microservice\n        `certified set-org`\n\n* v1.0.0\n\n  - [x] replace httpx with aiohttp (has better test client/server support).\n\n  - [x] change servers to services where appropriate\n\n* v1.1.0\n\n  - [x] fix biscuit\\_auth dependency version and change to uv packaging\n\n* v1.2.0\n\n  - [ ] CI and better test coverage\n\n  - [ ] better documentation for known\\_services\n        and interface for showing configuration contents\n\n* v1.2.1\n\n  - [ ] throw warning if id.crt does not contain the server's\n    hostname in SAN (since this will usually result in a connection error\n    from SSL)\n\n* v 1.3.0\n\n  - [ ] Better documentation and more helpful error messages\n\n  - [ ] Demo presentations and lessons learned\n\n  - [ ] CLI interface for biscuit creation / validation\n\n* v1.4.0\n\n  - [ ] add certificate serial numbers\n\n  - [ ] save a log of all certificates signed and revoked\n    utilize CSR-s?\n    https://cryptography.io/en/latest/x509/tutorial/#creating-a-certificate-signing-request-csr\n\n  - [ ] support nng TLS sockets\n\n  - [ ] support GRPC library\n\n* v1.5.0\n\n  - [ ] key rotation features and docs\n\n## Technology to watch\n\n- hardware certificate implementations (plug-ins?)\n\n- OAuth2 integrations / biscuit adoption\n\n# List of Useful Microservices\n\n* \u003chttps://gitlab.com/frobnitzem/planner_api\u003e\n\n* \u003chttps://github.com/frobnitzem/psik_api\u003e\n\n* \u003chttps://gitlab.com/frobnitzem/signer\u003e\n\n# References\n\n[mtls]: https://www.golinuxcloud.com/mutual-tls-authentication-mtls/ \"Mutual TLS\"\n\n[x509]: https://cryptography.io/en/latest/x509/tutorial/#creating-a-certificate-signing-request-csr \"Python x509 Cryptography HOWTO\"\n\n[openssl]: https://x509errors.org/guides/openssl \"OpenSSL: TLS Guide\" -- building a custom validator in C\n\n[exts]: https://www.golinuxcloud.com/add-x509-extensions-to-certificate-openssl/ \"Adding Extensions to x509\"\n\n[globus]: https://globus.stanford.edu/security.html\n\n## Use of TLS/certs in services\n\n[uvicorn]: https://github.com/encode/uvicorn/discussions/2307\n\n[rucio transfers]: https://rucio.cern.ch/documentation/operator/transfers/transfers-overview/\n\n[fts3 logging setup (enables TLS)]: https://fts3-docs.web.cern.ch/fts3-docs/docs/install/messaging.html\n\n[fts3 tls]: https://fts3-docs.web.cern.ch/fts3-docs/docs/developers/tls_shenanigans.html\n\n## more on custom attributes using openssl command\n\n- https://stackoverflow.com/questions/36007663/how-to-add-custom-field-to-certificate-using-openssl\n\n- https://stackoverflow.com/questions/17089889/openssl-x509v3-extended-key-usage -- config. file attributes\n\n- https://superuser.com/questions/947061/openssl-unable-to-find-distinguished-name-in-config/1118045 -- use a complete config\n\n## More on JWT/cookies/macaroons/biscuits\n\n[scitokens]: https://scitokens.org/\n\n[scitokens proposal]: https://scitokens.org/scitokens-proposal-public.pdf\n\n[scitokens presentation]: https://scitokens.org/presentations/SciTokens-GDB-Oct-2017.pdf\no\n\n[Indigo IAM JWT profiles]: https://indigo-iam.github.io/v/v1.9.0/docs/reference/configuration/jwt-profiles/\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fornl%2Fcertified","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fornl%2Fcertified","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fornl%2Fcertified/lists"}