{"id":25237362,"url":"https://github.com/filipmnowak/pyauthz","last_synced_at":"2025-12-31T14:21:08.675Z","repository":{"id":185464205,"uuid":"146358848","full_name":"filipmnowak/pyauthz","owner":"filipmnowak","description":"HTTP authentication/authorization scheme based on HMACs","archived":false,"fork":false,"pushed_at":"2024-04-08T21:19:24.000Z","size":22,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-14T22:26:10.697Z","etag":null,"topics":["api","authentication","authorization","python3","rest","signature-verification"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/filipmnowak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-08-27T21:58:36.000Z","updated_at":"2024-04-08T21:18:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"a49f77d8-c56c-4db2-942a-b417eecb6f87","html_url":"https://github.com/filipmnowak/pyauthz","commit_stats":null,"previous_names":["filipmnowak/pyauthz"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/filipmnowak/pyauthz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filipmnowak%2Fpyauthz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filipmnowak%2Fpyauthz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filipmnowak%2Fpyauthz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filipmnowak%2Fpyauthz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/filipmnowak","download_url":"https://codeload.github.com/filipmnowak/pyauthz/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filipmnowak%2Fpyauthz/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265849011,"owners_count":23838195,"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":["api","authentication","authorization","python3","rest","signature-verification"],"created_at":"2025-02-11T16:00:20.441Z","updated_at":"2025-12-31T14:21:08.646Z","avatar_url":"https://github.com/filipmnowak.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pyauthz \n\nVerify (authorize) or sign request using [httpsig](https://github.com/ahknight/httpsig/) module; based on:\n\n    * Signing HTTP Messages (draft-cavage-http-signatures-03) standard draft\n    * RFC 3230 - Instance Digests in HTTP\n    * RFC 5843 - Additional Hash Algorithms for HTTP Instance Digests\n\nPurpose of the module is to enable backend to backend conversation authorized with\nAPI keys but without exposing the key itself.\n\nIt acts as convenience layer and supplements [httpsig](https://github.com/ahknight/httpsig/) with:\n\n    * signature TTL\n    * request body digest to improve request integrity protection\n    * some help with verification key choice\n    * salt header to increase security of HMAC signature\n\nThis is experimantal software and it might not be fit for production usage! Use with caution, please report any issues.\n\n## Dependencies:\n\nBeside standard Python modules:\n\n* [httpsig 1.2.0](https://pypi.python.org/pypi/httpsig/1.2.0)\n\n## Usage\n\nBasic example:\n\n* in contenerized environments you may want to start with exporting json string\n  containing API keys you want to use (alternatively, you can provide id and key during class\n  instantialization):\n\n```bash\nexport PYAUTHZ_API_KEYS='{\"someid1\": \"somekey1\", \"someid2\": \"somekey2\", \"someid3\": \"somekey3\"}'\n```\n\n* import module:\n\n```python\n\u003e\u003e\u003e from pyauthz import HTTPSigAuthZ as z\n```\n\n* set required data (all of the headers from the requests fed to the method will be\n  used from creation of the signature):\n\n```python\n\u003e\u003e\u003e keyid_and_key = ('someid', 'somekey')\n\u003e\u003e\u003e req = {'headers': {\"Date\": \"Fri Oct  5 21:39:45 CEST 2018\", \"Host\": \n... \"example.com\"},'body': '{\"z\": 1, \"a\": 2 }', 'path': '/some/endpoint', 'method': 'GET'}\n```\n\n* to sign: create instance, and create signed headers dictionary:\n\n```python\n\u003e\u003e\u003e hs = z(req, keyid_and_key, 120)\n\u003e\u003e\u003e signed_headers = hs.sign_request()\n\u003e\u003e\u003e signed_headers\n{'date': 'Fri Oct  5 21:39:45 CEST 2018', 'host': 'example.com', 'signature-ttl': '120', 'pyauthz-salt': \n'SuUpmh78GxP/LctVk5HjsUfTp8LB4B6p+DIW8imSPXCPxSWsiW62nL+8DokvptG79t8VhJwxmRKSnetWPwpP7Q==', \n'digest': 'sha-256=wphcW6b30qVedo+SSQygk4jpW8TMy5/fEbFfTUL5PnM=', 'authorization': 'Signature \nkeyId=\"someid\",algorithm=\"hmac-sha256\",signature=\"Y9q4PlLX9wXEndz8Ggn13aiqq23Klk89hF0wbiWLHQc=\",\nheaders=\"(request-target) date host signature-ttl pyauthz-salt digest\"'}\n```\n\n* to verify, similar steps (please note order of the keys in the body of the request\nwas changed - this will work also, because we are generating `digest` header using\ncanonical form of the json payload):\n\n```python\n\u003e\u003e\u003e req = {'headers': signed_headers, 'body': '{\"a\": 2, \"z\": 1 }',\n... 'path': '/some/endpoint', 'method': 'GET'}\n\u003e\u003e\u003e hv = z(req, keyid_and_key)\n\u003e\u003e\u003e hv.verify_request()\nTrue\n\u003e\u003e\u003e\n```\n\n## Security\n\nScheme is susceptible to reply attack - potential attacker can \"records\" whole\nHTTP request, (including authorization header) and reply it until it is valid.\n\nThis is due to compromise between security and functionality (issue can be solved\nwith server-provided nonce, but this requires round trips - which are the\ncase in [HTTP Digest](https://en.wikipedia.org/wiki/Digest_access_authentication) auth) -\nthis module offers stateless authorization.\n\nTo lower the risk, please use TLS and tune `signature_ttl` parameter during class\ninitialization. \n\nEspecially in production environment, it is good idea to use TLS in addition to this module.\n\nIt is possible that HTTP client will add some extra headers, after signing procedure will take place, same\ncan be true if proxy servers come into play.\nHTTP headers can also be added during main-in-the-middle attack (especially in case of non-TLS, plain HTTP connection).\nThose headers can change behavior of the remote HTTP server or application (verifier).\n\n## Contributing\n\nYou are more then welcome to fork it and contribute by creating pull requests.\nIn case of any other need, please let me know.\n\nPlease make sure your code is compliant with [PEP8 standard](https://www.python.org/dev/peps/pep-0008/), with some tweaks allowed:\n\n* E402 - in tests, module-level imports not being placed at the top of the source file are fine.\n* E501 - maximum line length is set to 92 characters (more practical and still tidy / readable)\n* E265 - it is OK to comment code without adding space after `#`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilipmnowak%2Fpyauthz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffilipmnowak%2Fpyauthz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilipmnowak%2Fpyauthz/lists"}