Metadata-Version: 2.1
Name: keyrings.osx-keychain-keys
Version: 0.0.2
Summary: OSX Keychain backend for key-pairs
Home-page: https://github.com/dany74q/keyrings.osx_keychain_keys
Author: Danny Shemesh
Author-email: dany74q@gmail.com
License: UNKNOWN
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.6
Requires-Dist: pyobjc (>=6.2.2)
Requires-Dist: cryptography (>=3.1)
Requires-Dist: keyring (>=21.4.0)
Provides-Extra: docs
Requires-Dist: sphinx (>=3.2.1) ; extra == 'docs'
Requires-Dist: jaraco.packaging (>=3.2) ; extra == 'docs'
Requires-Dist: rst.linker (>=2.0.0) ; extra == 'docs'
Provides-Extra: testing
Requires-Dist: pytest (>=6.0.1) ; extra == 'testing'
Requires-Dist: pytest-flake8 (>=1.0.6) ; extra == 'testing'
Requires-Dist: pytest-black (>=0.3.11) ; extra == 'testing'
Requires-Dist: pytest-cov (>=2.10.1) ; extra == 'testing'

.. image:: https://img.shields.io/pypi/v/keyrings.osx_keychain_keys.svg
   :target: https://pypi.org/project/keyrings.osx-keychain-keys

.. image:: https://img.shields.io/pypi/pyversions/osx_keychain_keys.svg

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
   :target: https://github.com/psf/black
   :alt: Code style: Black

.. .. image:: https://readthedocs.org/projects/keyrings.osx_keychain_keys/badge/?version=latest
..    :target: https://keyrings.osx_keychain_keys.readthedocs.io/en/latest/?badge=latest

.. image:: https://img.shields.io/github/workflow/status/dany74q/keyrings.osx_keychain_keys/CI
   :target: https://github.com/psf/black
   :alt: Code style: Black

|

This library is a backend addon for `keyring <https://github.com/jaraco/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
* 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

Using This Backend
==================

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

.. code-block:: python

    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, a release
will be automatically deployed to pypi.

Running Tests
=============

To run the tests locally (a darwin machine is required), install and invoke
`tox <https://pypi.org/project/tox>`_.


