)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"baadbeacd1fb9c76c8a2f77f9042c5e4279f2fd6","unresolved":true,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"tempauth: Support fernet tokens"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Add a new config option, fernet_key. If set, use fernet tokens for"},{"line_number":10,"context_line":"primary storage rather than memcached. This allows generated tokens"},{"line_number":11,"context_line":"to be validated even if memcached is restarted. Note that the key"},{"line_number":12,"context_line":"must match across all proxies in the cluster."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"6824a320_b67ef4ce","line":9,"range":{"start_line":9,"start_character":0,"end_line":9,"end_character":36},"updated":"2023-03-02 05:48:53.000000000","message":"*grumble* Well this all needs to be updated...","commit_id":"4ed7cede2534bb0b5608207a99941ae7044c1f43"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3bffbae0c5837a386d7ad570ec6bc116e8f93229","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"8f272bed_c794485f","updated":"2025-04-30 22:37:53.000000000","message":"I\u0027m\u0027a assume you just forgot to vote, Matt ;-)","commit_id":"74030236ad1ba955f3904917dbc405027e5d6905"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"9f4e321228165dbdc9f33fcd48658c267d3828a4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"d12a21f8_6fb213d8","updated":"2025-04-25 23:33:56.000000000","message":"Looks like a rebase to me.","commit_id":"74030236ad1ba955f3904917dbc405027e5d6905"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b99c25ebf9932688463f30d251b43d97e0358596","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"6247eb0c_f64e8d4b","updated":"2025-04-30 21:29:58.000000000","message":"Yup this is an awesome feature and based on Tim\u0027s latest tests and the +2 from Pete, let\u0027s land it!","commit_id":"74030236ad1ba955f3904917dbc405027e5d6905"}],"etc/proxy-server.conf-sample":[{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"d2372497da262f3b00a55a28c5105a460ba63069","unresolved":true,"context_lines":[{"line_number":397,"context_line":"#"},{"line_number":398,"context_line":"# If set, use fernet keys for storage, rather than relying on memcached."},{"line_number":399,"context_line":"# To generate a fernet key, use `openssl rand -base64 32 | tr \u0027+/\u0027 \u0027-_\u0027`"},{"line_number":400,"context_line":"# fernet_key \u003d \u003c32 url-safe base64-encoded bytes\u003e"},{"line_number":401,"context_line":"#"},{"line_number":402,"context_line":"# Lastly, you need to list all the accounts/users you want here. The format is:"},{"line_number":403,"context_line":"#   user_\u003caccount\u003e_\u003cuser\u003e \u003d \u003ckey\u003e [group] [group] [...] [storage_url]"}],"source_content_type":"application/octet-stream","patch_set":1,"id":"b7219e3f_57fbdc2c","line":400,"updated":"2022-10-18 22:48:07.000000000","message":"Does this setting need to be the same on every proxy node? E.g. can it be that one acquires the token at proxy A with Tempauth, then talks to proxy B, sends the token, and then what?","commit_id":"66402337f69ef8fddd9c388094d7dfa9e6a37fbf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f5758a809f601d63785579f3804a1c250d35c0d2","unresolved":true,"context_lines":[{"line_number":397,"context_line":"#"},{"line_number":398,"context_line":"# If set, use fernet keys for storage, rather than relying on memcached."},{"line_number":399,"context_line":"# To generate a fernet key, use `openssl rand -base64 32 | tr \u0027+/\u0027 \u0027-_\u0027`"},{"line_number":400,"context_line":"# fernet_key \u003d \u003c32 url-safe base64-encoded bytes\u003e"},{"line_number":401,"context_line":"#"},{"line_number":402,"context_line":"# Lastly, you need to list all the accounts/users you want here. The format is:"},{"line_number":403,"context_line":"#   user_\u003caccount\u003e_\u003cuser\u003e \u003d \u003ckey\u003e [group] [group] [...] [storage_url]"}],"source_content_type":"application/octet-stream","patch_set":1,"id":"c0df5df9_02458e34","line":400,"in_reply_to":"618ded34_b01d6bc2","updated":"2023-02-15 17:13:00.000000000","message":"Point taken -- I\u0027ll look at switching to something like we do for encryption; see https://github.com/openstack/swift/blob/2.31.0/etc/proxy-server.conf-sample#L1232-L1243\n\nIn short, allow multiple `fernet_key_\u003ckey_id\u003e` config options, any of which can be used to decrypt, and a `active_fernet_key_id \u003d \u003ckey_id\u003e` to specify which one to use for new encryptions. If blank or omitted, use the old-style tokens -- this is a little different from what we do for encryption, but I think we *would\u0027ve* done this if we\u0027d been thinking more about key rotation from the start.\n\nConfig change then looks like:\n\n- Push out `fernet_key_2023_02 \u003d ...` (say) to nodes one by one, restarting proxies as you go. When done, everyone can read such tokens, but no one is writing them.\n- Push out `active_fernet_key_id \u003d 2023_02` to nodes one by one, restarting proxies as you go. Everyone gradually flops over to issuing fernet tokens.\n\nThis also supports key rotation; next month, you\u0027d:\n\n- Push out `fernet_key_2023_03 \u003d ...`\n- Push out `active_fernet_key_id \u003d 2023_03`\n- Wait for all old tokens to have expired\n- Push out a config to remove `fernet_key_2023_02`","commit_id":"66402337f69ef8fddd9c388094d7dfa9e6a37fbf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f58258a7c83bd809563946f04a0c436b41759400","unresolved":true,"context_lines":[{"line_number":397,"context_line":"#"},{"line_number":398,"context_line":"# If set, use fernet keys for storage, rather than relying on memcached."},{"line_number":399,"context_line":"# To generate a fernet key, use `openssl rand -base64 32 | tr \u0027+/\u0027 \u0027-_\u0027`"},{"line_number":400,"context_line":"# fernet_key \u003d \u003c32 url-safe base64-encoded bytes\u003e"},{"line_number":401,"context_line":"#"},{"line_number":402,"context_line":"# Lastly, you need to list all the accounts/users you want here. The format is:"},{"line_number":403,"context_line":"#   user_\u003caccount\u003e_\u003cuser\u003e \u003d \u003ckey\u003e [group] [group] [...] [storage_url]"}],"source_content_type":"application/octet-stream","patch_set":1,"id":"faa134a4_cf3b9a62","line":400,"in_reply_to":"b7219e3f_57fbdc2c","updated":"2023-02-14 20:11:11.000000000","message":"Yes, the secret would need to be shared across all proxies. I\u0027ll add that to the description above.","commit_id":"66402337f69ef8fddd9c388094d7dfa9e6a37fbf"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"306552f0c1fd80f2dd36baeec1bb1f4eb4723746","unresolved":false,"context_lines":[{"line_number":397,"context_line":"#"},{"line_number":398,"context_line":"# If set, use fernet keys for storage, rather than relying on memcached."},{"line_number":399,"context_line":"# To generate a fernet key, use `openssl rand -base64 32 | tr \u0027+/\u0027 \u0027-_\u0027`"},{"line_number":400,"context_line":"# fernet_key \u003d \u003c32 url-safe base64-encoded bytes\u003e"},{"line_number":401,"context_line":"#"},{"line_number":402,"context_line":"# Lastly, you need to list all the accounts/users you want here. The format is:"},{"line_number":403,"context_line":"#   user_\u003caccount\u003e_\u003cuser\u003e \u003d \u003ckey\u003e [group] [group] [...] [storage_url]"}],"source_content_type":"application/octet-stream","patch_set":1,"id":"09505743_0174dda9","line":400,"in_reply_to":"c0df5df9_02458e34","updated":"2023-03-15 22:52:52.000000000","message":"Ack","commit_id":"66402337f69ef8fddd9c388094d7dfa9e6a37fbf"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"e2d53a2f984825563a9540f1eefc02402741152b","unresolved":true,"context_lines":[{"line_number":397,"context_line":"#"},{"line_number":398,"context_line":"# If set, use fernet keys for storage, rather than relying on memcached."},{"line_number":399,"context_line":"# To generate a fernet key, use `openssl rand -base64 32 | tr \u0027+/\u0027 \u0027-_\u0027`"},{"line_number":400,"context_line":"# fernet_key \u003d \u003c32 url-safe base64-encoded bytes\u003e"},{"line_number":401,"context_line":"#"},{"line_number":402,"context_line":"# Lastly, you need to list all the accounts/users you want here. The format is:"},{"line_number":403,"context_line":"#   user_\u003caccount\u003e_\u003cuser\u003e \u003d \u003ckey\u003e [group] [group] [...] [storage_url]"}],"source_content_type":"application/octet-stream","patch_set":1,"id":"618ded34_b01d6bc2","line":400,"in_reply_to":"faa134a4_cf3b9a62","updated":"2023-02-15 00:53:33.000000000","message":"Very well, but what if you are in the process of upgrading the cluster, and then you change this configuration and restart nodes one by one? Is there a requirement to maneuver at LB level?\n\nFor example. Suppose you have 4 proxies: A...D. Reconfigure LB to exclude A,B. Shut down A,B. Change config to Fernet. Boot A,B. Switch LB to A,B, exclude C,D. At this point, old-style tokens, issued by C,D will be verified by A,B. But tokens issued by A,B will be Fernet ones. Now you can change LB back to allow all of A...B. Is this how this is supposed to be handled?","commit_id":"66402337f69ef8fddd9c388094d7dfa9e6a37fbf"}],"swift/common/middleware/tempauth.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cd7554b674159412913a44fd9e17e37353b218c5","unresolved":true,"context_lines":[{"line_number":440,"context_line":"        return groups"},{"line_number":441,"context_line":""},{"line_number":442,"context_line":"    def groups_from_fernet(self, env, token):"},{"line_number":443,"context_line":"        for key in self.fernet_keys.items():"},{"line_number":444,"context_line":"            try:"},{"line_number":445,"context_line":"                return key.decrypt("},{"line_number":446,"context_line":"                    token.encode(\u0027ascii\u0027),"}],"source_content_type":"text/x-python","patch_set":3,"id":"326e3c99_16c57cff","line":443,"updated":"2023-03-15 18:36:10.000000000","message":"Would probably be better to use https://cryptography.io/en/latest/fernet/#cryptography.fernet.MultiFernet than roll our own multi-key thing...","commit_id":"4ed7cede2534bb0b5608207a99941ae7044c1f43"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"306552f0c1fd80f2dd36baeec1bb1f4eb4723746","unresolved":true,"context_lines":[{"line_number":440,"context_line":"        return groups"},{"line_number":441,"context_line":""},{"line_number":442,"context_line":"    def groups_from_fernet(self, env, token):"},{"line_number":443,"context_line":"        for key in self.fernet_keys.items():"},{"line_number":444,"context_line":"            try:"},{"line_number":445,"context_line":"                return key.decrypt("},{"line_number":446,"context_line":"                    token.encode(\u0027ascii\u0027),"}],"source_content_type":"text/x-python","patch_set":3,"id":"9b0740d8_ec58bc1a","line":443,"in_reply_to":"326e3c99_16c57cff","updated":"2023-03-15 22:52:52.000000000","message":"A new dependency, not sure I like.","commit_id":"4ed7cede2534bb0b5608207a99941ae7044c1f43"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2a761e40c11ae60a0df0142fbb997961426aa5f7","unresolved":true,"context_lines":[{"line_number":440,"context_line":"        return groups"},{"line_number":441,"context_line":""},{"line_number":442,"context_line":"    def groups_from_fernet(self, env, token):"},{"line_number":443,"context_line":"        for key in self.fernet_keys.items():"},{"line_number":444,"context_line":"            try:"},{"line_number":445,"context_line":"                return key.decrypt("},{"line_number":446,"context_line":"                    token.encode(\u0027ascii\u0027),"}],"source_content_type":"text/x-python","patch_set":3,"id":"41f498fc_5bc607b5","line":443,"in_reply_to":"9b0740d8_ec58bc1a","updated":"2024-06-13 22:29:20.000000000","message":"\u003e A new dependency\n\nNot really -- we\u0027ve already got a dependency on `cryptography` for the encryption middleware.","commit_id":"4ed7cede2534bb0b5608207a99941ae7044c1f43"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b99c25ebf9932688463f30d251b43d97e0358596","unresolved":true,"context_lines":[{"line_number":778,"context_line":"            compressed \u003d zlib.compress(groups)"},{"line_number":779,"context_line":"            if len(compressed) \u003c len(groups):"},{"line_number":780,"context_line":"                token_prefix \u003d \u0027zftk\u0027  # nosec: B105"},{"line_number":781,"context_line":"                groups \u003d compressed"},{"line_number":782,"context_line":"            token \u003d \u0027\u0027.join(["},{"line_number":783,"context_line":"                self.reseller_prefix,"},{"line_number":784,"context_line":"                token_prefix,"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a752ece_d2c65c32","line":781,"updated":"2025-04-30 21:29:58.000000000","message":"this is a cool optimisation!","commit_id":"74030236ad1ba955f3904917dbc405027e5d6905"}]}
