Skip to content

Latest commit

 

History

History
115 lines (78 loc) · 4.45 KB

README.rst

File metadata and controls

115 lines (78 loc) · 4.45 KB
PyPi version

Python version

Code style: Black Read the docs

CI workflow

This library is a backend addon for keyring, it provides a backend that manages OSX keychain key-class items.

Supported features:

  • Auto-generating keys via SecKeyCreateRandomKey
  • Importing existing keys of various formats via SecItemAdd
  • Storing keys in keychain, or generating transient keys
  • Storing keys in the secure enclave (T2 chip - 'TPM'); for code-signed interpreters
  • Limiting key management to specific access groups; for code-signed interpreters
  • Making keys non-extractable, so that the key content could not be retrieved, but only used for signing or encryption

Installation

Run the following (on a darwin machine):

$ pip install keyrings.osx_keychain_keys

Using This Backend

One can utilize this backend both programatically, or from the CLI.

import keyring
from keyrings.osx_keychain_keys.backend import OSXKeychainKeysBackend, OSXKeychainKeyType, OSXKeyChainKeyClassType

backend = OSXKeychainKeysBackend(
    key_type=OSXKeychainKeyType.RSA, # Key type, e.g. RSA, RC, DSA, ...
    key_class_type=OSXKeyChainKeyClassType.Private, # Private key, Public key, Symmetric-key
    key_size_in_bits=4096,
    is_permanent=True, # If set, saves the key in keychain; else, returns a transient key
    use_secure_enclave=False, # Saves the key in the T2 (TPM) chip, requires a code-signed interpreter
    access_group=None, # Limits key management and retrieval to set group, requires a code-signed interpreter
    is_extractable=True # If set, private key is extractable; else, it can't be retrieved, but only operated against
)

keyring.set_keyring(backend)

# If password is not set - a key is generated
keyring.set_password('some-label', 'some-tag', password=None)

# If password is set - it could be a file path to a key to import to keychain
keyring.set_password('some-label', 'some-tag', '/tmp/my-private.key')
# It could also be the key-data itself
keyring.set_password('some-label', 'some-tag', '-----BEGIN RSA PRIVATE KEY----\n....')

# Returns a python-wrapped (using hazmat cryptography lib) private / public key
keyring.get_password('some-label', 'some-tag')

# Deletes a key from keychain
keyring.delete_password('some-label', 'some-tag')

See more examples in keyrings/osx_keychain_keys/examples and keyrings/osx_keychain_keys/tests.

Command-line Utility

One can also use the keyring CLI to operate against this backend:

$ keyring -b keyrings.osx_keychain_keys.backend.OSXKeychainKeysBackend set "some-label" "some-tag"

Security Considerations

Using mac's keychain has some caveats that should be noted, namely:

  • Some keychain APIs require the invoking application (the python interpreter, in this case) to be code-signed with specific Apple entitlements, namely:

    • Saving the key to the secure enclave (T2 / TPM chip)
    • Limiting access via access controls (i.e. requiring touch-id / password before key retrieval)
    • Limiting key management to specific access groups
  • By default, all inserted keys are accessible to the runnable executable, meaning the interpreter you use can manage the generated or imported keys.

    If you use a virtualenv, you may create one with $> venv --copies to limit accessibility to the specific venv python binary.

Making Releases

A CI/CD pipeline is setup on github - once a PR is merged to master, a pre-release will be automatically deployed to github; When a release is tagged, it will be automatically deployed to pypi.

Running Tests

To run the tests locally (a darwin machine is required), install and invoke tox.