{"id":23136073,"url":"https://github.com/sheagcraig/macsesh","last_synced_at":"2025-08-17T10:31:43.444Z","repository":{"id":44162306,"uuid":"258766022","full_name":"sheagcraig/MacSesh","owner":"sheagcraig","description":"Tools for letting the macOS Keychain verify certs for python requests","archived":false,"fork":false,"pushed_at":"2023-12-01T18:31:06.000Z","size":80,"stargazers_count":28,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-29T05:52:03.249Z","etag":null,"topics":["https","macos","python-requests","requests","tacos"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sheagcraig.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2020-04-25T12:06:36.000Z","updated_at":"2025-07-28T01:45:51.000Z","dependencies_parsed_at":"2023-11-27T16:49:33.386Z","dependency_job_id":null,"html_url":"https://github.com/sheagcraig/MacSesh","commit_stats":{"total_commits":29,"total_committers":2,"mean_commits":14.5,"dds":"0.27586206896551724","last_synced_commit":"e24e5040ae86f4438ef9712b215f5a6d26586a5a"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/sheagcraig/MacSesh","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sheagcraig%2FMacSesh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sheagcraig%2FMacSesh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sheagcraig%2FMacSesh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sheagcraig%2FMacSesh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sheagcraig","download_url":"https://codeload.github.com/sheagcraig/MacSesh/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sheagcraig%2FMacSesh/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270837401,"owners_count":24654374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"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":["https","macos","python-requests","requests","tacos"],"created_at":"2024-12-17T12:18:30.903Z","updated_at":"2025-08-17T10:31:43.158Z","avatar_url":"https://github.com/sheagcraig.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MacSesh\nThis package allows the popular requests library to use the macOS\nkeychain for validating a server, and for doing client cert auth.\nIts original use-case was for Mac admins wanting to use python requests\nand certs provided by an MDM for TLS, Specifically, client cert auth\nusing SCEP profiles, and x509 payloads for server validation.\n\n### Installing\n\n```\npip install MacSesh\n```\n\nIf you want to install from a source distribution, clone and run below. \n\n```\npip install .\n```\n\n## Example Usage:\nValidate using a trusted cert from the keychain:\n\n```\n\u003e\u003e\u003e import macsesh\n\u003e\u003e\u003e sesh = macsesh.Session()\n\u003e\u003e\u003e response = sesh.get('https://nethack.org')\n```\nIf you want to use the \"basic\" requests API without creating a session:\n\n```\n\u003e\u003e\u003e macsesh.inject_into_requests()\n\u003e\u003e\u003e requests.get('https://en.wikipedia.org/wiki/Taco')  # Uses keychain\n```\n\nClient cert auth:\n\n```\n\u003e\u003e\u003e import macsesh\n\u003e\u003e\u003e sesh = macsesh.Session()\n\u003e\u003e\u003e response = sesh.get('https://nethack.org', cert='My Identity Cert')\n```\n\n## Validating a server\nmacsesh uses any of the _trusted_ certs from keychains included in the\ncurrent user's keychain search list, as well as the system roots.\nTypically, this search list consists of:\n- The user's default keychain at `~/Library/Keychains/login.keychain`\n- The system keychain at `/Library/Keychains/System.keychain`\n- The System Roots keychain at\n  `/System/Library/Keychains/SystemRootCertificates.keychain`.\n\nCerts in the system roots are implicitly trusted. Certs from other\nkeychains must be marked as trusted for this purpose or they won't be\nincluded.\n\nWhen using macsesh, just leave the requests `verify` at its default of\n`True` and macsesh will do the rest.\n\n## Client cert auth\nmacsesh can also do client cert auth from the keychain, currently only\nwith the `SecureTransportAdapter`. The other adapter types can do client\ncert auth as well of course, but they require the identity to be\navailable on the filesystem just like regular requests.\n\nTo specify a certificate to use, provide the Common Name of the cert to\nrequests' normal `cert` argument as in the example above. As the\nkeychain may have multiple certs which match , macsesh performs some\nadditional filtering.\n1. The query does a \"subject contains\" search with the CN provided, so\n   for exmaple `cert='taco'` could match a CN of `taco truck` or `taco\n   party`.\n2. After the \"subject contains\" search, macsesh will drop anything that\n   is not an exact string match.\n3. The resulting certs may have been renewed, and the old certs are\n   still in the keychain. macsesh sorts them by \"not valid after\" date\n   and picks the one with the longest lifespan.\n\n## Advanced\n\n### Cleanup\nIf for some reason you want to revert to \"normal\" requests (probably \nusing certifi), in the same python process, you'll need to remove this\nmodule's injected stuff from urllib3 or requests.\n\nRemove the `SSLContext` if you used any of the Sessions:\n```macsesh.extract_from_urllib3()```\nClean up after using the \"basic\" API:\n```macsesh.extract_from_requests()```\n\nAny certs added to the keychains after starting a session will\nnot be available. Digging down in and updating the SSLContext is rough;\njust make a new session if you have this need!\n\n### Choosing a session type\nmacsesh provides three different types of requests `Session` classes.\nWhile we probably only need the `Session`, the other two are included\nfor posterity since they are interesting and potentially useful.\n\n1. If in doubt, use `Session` It uses the securetransport module\n   contributed to urllib3 as a base SSLContext. Pip, for example, uses\n   this on macOS.  The securetransport module uses an entirely different\n   `SSLContext`, using ctypes to connect to the macOS `Security` \n   framework. macsesh then injects additional code into the urllib3\n   code to use the keychain instead of conforming to the OpenSSL\n   approach of using paths to files. If you need to do client cert auth\n   from keychain identities, this is the one you want.\n1. `KeychainSession` uses a custom SSLContext, requests Adapter, and\n   requests Session, and injects the SSLContext into urllib3. The certs\n   for validation are dumped from the keychain and held in memory. The\n   goal of this approach is to use the minimum amount of messing about\n   to achieve cert validation.\n3. `SimpleKeychainSession` circumvents the normal flow of session\n   startup, and tells the SSLContext to load its trust information\n   up front rather than waiting for a bunch of internal checks to decide\n   the context needs to load the trust store. It uses the same method\n   as the `KeychainSession` and functionally shouldn't be any different.\n\n### What about cert auth for `SimpleKeychainSession` and\n`KeychainSession`?\n\nI can try implementing looking up and retrieving certs by name for the\nother \"strategies\", but I'm not sure how much utility there is for that,\nas the keys would have to be exportable. At that point, just export them\nand use regular old requests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsheagcraig%2Fmacsesh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsheagcraig%2Fmacsesh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsheagcraig%2Fmacsesh/lists"}