)]}'
{"keystone/common/fernet_key_store/backends/base.py":[{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"a79729365d4bcccbda38862c031fe73ca32109dc","unresolved":false,"context_lines":[{"line_number":21,"context_line":"class FernetUtilsDriver(object):"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    @abc.abstractmethod"},{"line_number":24,"context_line":"    def validate_key_repository():"},{"line_number":25,"context_line":"        \"\"\"Validate permissions on the key repository directory.\"\"\""},{"line_number":26,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1a6eadb0_b3771dd3","line":24,"updated":"2016-12-21 00:42:58.000000000","message":"Add a parameter to these to indicate which repository it is.  Create an enumerated value that, at a minimum has `token` and `credential` as its type.","commit_id":"dd194f38a56e5cd4f10adfc8974abda09dfa6962"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"a816684d06c30ca92ef6e248ae7556892f6c6c28","unresolved":false,"context_lines":[{"line_number":21,"context_line":"class FernetUtilsDriver(object):"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    @abc.abstractmethod"},{"line_number":24,"context_line":"    def validate_key_repository():"},{"line_number":25,"context_line":"        \"\"\"Validate permissions on the key repository directory.\"\"\""},{"line_number":26,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"ba5201f7_a6bbb70d","line":24,"in_reply_to":"1a6eadb0_b3771dd3","updated":"2016-12-29 15:48:30.000000000","message":"I\u0027m not sure I agree with this part. A fernet repository is just a set of keys somewhere, and currently that somewhere is on disk. We don\u0027t expect the keys to know what they are suppose to be used for. Instead we leave it to whatever needs the encrypting done. If something needs to have a value encrypted or decrypted, it needs to specifically say which repository it needs to interact with [0] [1]. This makes the fernet token provider responsible for interacting with the repository dedicated to token encryption. The same applies with the fernet credentials provider. The only relationship the current key repository directories have with the system that uses them is the default naming convention (`/etc/keystone/fernet-keys/`, `/etc/keystone/credential-keys/`). But there is nothing stopping someone from swapping those values through config to be something more obscure.\n\nI think having the drivers and keys keep track of what they are encrypting is unnecessary coupling if we already expect manager to interact with the proper key repository.\n\n\n[0] https://github.com/openstack/keystone/blob/686f9d583eaa5f015d6b8b995c2f4243392ffbce/keystone/credential/providers/fernet/core.py#L45-L46\n\n[1] https://github.com/openstack/keystone/blob/686f9d583eaa5f015d6b8b995c2f4243392ffbce/keystone/token/providers/fernet/token_formatters.py#L59-L62","commit_id":"dd194f38a56e5cd4f10adfc8974abda09dfa6962"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"a79729365d4bcccbda38862c031fe73ca32109dc","unresolved":false,"context_lines":[{"line_number":26,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    @abc.abstractmethod"},{"line_number":29,"context_line":"    def create_key_directory():"},{"line_number":30,"context_line":"        \"\"\"Attempt to create the key directory."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"        Create key directory if it doesn\u0027t exist and if it is necessary."}],"source_content_type":"text/x-python","patch_set":2,"id":"1a6eadb0_f3819590","line":29,"updated":"2016-12-21 00:42:58.000000000","message":"change directory to repository","commit_id":"dd194f38a56e5cd4f10adfc8974abda09dfa6962"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"a79729365d4bcccbda38862c031fe73ca32109dc","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    @abc.abstractmethod"},{"line_number":37,"context_line":"    def initialize_key_repository():"},{"line_number":38,"context_line":"        \"\"\"Create a key repository and bootstrap it with a key.\"\"\""},{"line_number":39,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":40,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1a6eadb0_7344a573","line":37,"updated":"2016-12-21 00:42:58.000000000","message":"merge this with the create_directory function above.","commit_id":"dd194f38a56e5cd4f10adfc8974abda09dfa6962"},{"author":{"_account_id":2218,"name":"Adam Young","email":"adam@younglogic.com","username":"ayoung"},"change_message_id":"a79729365d4bcccbda38862c031fe73ca32109dc","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        raise exception.NotImplemented()  # pragma: no cover"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    @abc.abstractmethod"},{"line_number":42,"context_line":"    def rotate_keys():"},{"line_number":43,"context_line":"        \"\"\"Create a new primary key and revoke excess active keys."},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"        Key rotation utilizes the following behaviors:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a6eadb0_f358b558","line":42,"updated":"2016-12-21 00:42:58.000000000","message":"If you are going to include this, then also have an \"inject key\" and \"extract key\" function.  To start, they can be unimplemented in the default impl, but really this is workflow separate from accessing keys.  Most real deployments can\u0027t do this on the Keystone server, but rather do it as part of config management.","commit_id":"dd194f38a56e5cd4f10adfc8974abda09dfa6962"}],"keystone/common/fernet_key_store/core.py":[{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"a363b9f3dd5723fd1e5590f58869a8a7079596c2","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    def __init__(self):"},{"line_number":36,"context_line":"        super(Manager, self).__init__(CONF.fernet_tokens.key_store_driver)"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def initialize_key_repository(self, key_repository,"},{"line_number":39,"context_line":"                                  max_active_keys,"},{"line_number":40,"context_line":"                                  keystone_user_id\u003dNone,"},{"line_number":41,"context_line":"                                  keystone_group_id\u003dNone):"},{"line_number":42,"context_line":"        self.driver.initialize_key_repository(key_repository,"},{"line_number":43,"context_line":"                                              max_active_keys,"},{"line_number":44,"context_line":"                                              keystone_user_id,"},{"line_number":45,"context_line":"                                              keystone_group_id)"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    def rotate_keys(self, key_repository,"},{"line_number":48,"context_line":"                    max_active_keys,"},{"line_number":49,"context_line":"                    keystone_user_id\u003dNone,"},{"line_number":50,"context_line":"                    keystone_group_id\u003dNone):"},{"line_number":51,"context_line":"        self.driver.rotate_keys(key_repository,"},{"line_number":52,"context_line":"                                max_active_keys,"},{"line_number":53,"context_line":"                                keystone_user_id\u003dNone,"},{"line_number":54,"context_line":"                                keystone_group_id\u003dNone)"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    def validate_key_repository(self, key_repository,"},{"line_number":57,"context_line":"                                requires_write\u003dFalse):"},{"line_number":58,"context_line":"        return self.driver.validate_key_repository(key_repository,"},{"line_number":59,"context_line":"                                                   requires_write)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    def load_keys(self, key_repository, max_active_keys):"},{"line_number":62,"context_line":"        return self.driver.load_keys(key_repository, max_active_keys)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def create_key_directory(self, key_repository,"},{"line_number":65,"context_line":"                             keystone_user_id\u003dNone,"},{"line_number":66,"context_line":"                             keystone_group_id\u003dNone):"},{"line_number":67,"context_line":"        return self.driver.create_key_directory(key_repository,"},{"line_number":68,"context_line":"                                                keystone_user_id,"},{"line_number":69,"context_line":"                                                keystone_group_id)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_e460f0d1","line":69,"range":{"start_line":38,"start_character":0,"end_line":69,"end_character":66},"updated":"2016-09-07 01:35:31.000000000","message":"if it only bypasses all the calls and params, it doesn\u0027t need to implement them. see https://github.com/openstack/keystone/blob/83e3c00/keystone/common/manager.py#L185","commit_id":"f3e858db1eab5e32bdf15cd7d63be03e59e6130e"},{"author":{"_account_id":21465,"name":"Mikhail Nikolaenko","email":"mnikolaenko@protonmail.com","username":"mnikolaenko"},"change_message_id":"e632e3be890dff90b645bec295da85fc26d42bcd","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    def __init__(self):"},{"line_number":36,"context_line":"        super(Manager, self).__init__(CONF.fernet_tokens.key_store_driver)"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def initialize_key_repository(self, key_repository,"},{"line_number":39,"context_line":"                                  max_active_keys,"},{"line_number":40,"context_line":"                                  keystone_user_id\u003dNone,"},{"line_number":41,"context_line":"                                  keystone_group_id\u003dNone):"},{"line_number":42,"context_line":"        self.driver.initialize_key_repository(key_repository,"},{"line_number":43,"context_line":"                                              max_active_keys,"},{"line_number":44,"context_line":"                                              keystone_user_id,"},{"line_number":45,"context_line":"                                              keystone_group_id)"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    def rotate_keys(self, key_repository,"},{"line_number":48,"context_line":"                    max_active_keys,"},{"line_number":49,"context_line":"                    keystone_user_id\u003dNone,"},{"line_number":50,"context_line":"                    keystone_group_id\u003dNone):"},{"line_number":51,"context_line":"        self.driver.rotate_keys(key_repository,"},{"line_number":52,"context_line":"                                max_active_keys,"},{"line_number":53,"context_line":"                                keystone_user_id\u003dNone,"},{"line_number":54,"context_line":"                                keystone_group_id\u003dNone)"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    def validate_key_repository(self, key_repository,"},{"line_number":57,"context_line":"                                requires_write\u003dFalse):"},{"line_number":58,"context_line":"        return self.driver.validate_key_repository(key_repository,"},{"line_number":59,"context_line":"                                                   requires_write)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    def load_keys(self, key_repository, max_active_keys):"},{"line_number":62,"context_line":"        return self.driver.load_keys(key_repository, max_active_keys)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def create_key_directory(self, key_repository,"},{"line_number":65,"context_line":"                             keystone_user_id\u003dNone,"},{"line_number":66,"context_line":"                             keystone_group_id\u003dNone):"},{"line_number":67,"context_line":"        return self.driver.create_key_directory(key_repository,"},{"line_number":68,"context_line":"                                                keystone_user_id,"},{"line_number":69,"context_line":"                                                keystone_group_id)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_3405b8c1","line":69,"range":{"start_line":38,"start_character":0,"end_line":69,"end_character":66},"in_reply_to":"9a89bdaa_e460f0d1","updated":"2016-09-12 11:51:58.000000000","message":"Done. Thank you!","commit_id":"f3e858db1eab5e32bdf15cd7d63be03e59e6130e"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"a816684d06c30ca92ef6e248ae7556892f6c6c28","unresolved":false,"context_lines":[{"line_number":21,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"@dependency.provider(\u0027fernet_key_store_api\u0027)"},{"line_number":25,"context_line":"class Manager(manager.Manager):"},{"line_number":26,"context_line":"    \"\"\"Default pivot point for the Fernet key store backend."},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"ba5201f7_262507ab","line":24,"updated":"2016-12-29 15:48:30.000000000","message":"What is going to use this api, other managers? The `keystone-manage` CLI? I can see a use case for other managers to be able to pass something to a separate API to encrypt or decrypt it [0], but I\u0027m not sure if exposing key rotation and repository management in an API is the right approach. I could be missing a use case though. The current approach to our file-based repository management is to call utility functions from `keystone-manage` to make new keys, rename them in rotations, and remove them when necessary. I think allowing other storage mechanisms for fernet keys would consist of making the existing utility methods pluggable through config without exposing their management functions through a manager class, but through `keystone-manage`.\n\nThat way, regardless of the fernet key store backend you have defined in your configuration, you should be able to do `keystone-manage fernet_setup` and get a set of file-based keys (like you do today), or a repository of fernet keys somewhere else.\n\n\n[0] https://github.com/openstack/keystone/blob/686f9d583eaa5f015d6b8b995c2f4243392ffbce/keystone/credential/core.py#L68-L70","commit_id":"dd194f38a56e5cd4f10adfc8974abda09dfa6962"}]}
