)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"65e7d250863f7d3b72c22e4d34d0c325b0d4ae2e","unresolved":true,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"proxy-logging: create new field for s3_access_key_id"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Adding new field to be able to log the access key during the s2api"},{"line_number":10,"context_line":"calls. Also adding the minimal set of regression tests."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Signed-off-by: Vitaly Bordyug \u003cvbordug@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"98a4a536_050e89d6","line":9,"updated":"2025-07-16 19:42:31.000000000","message":"s/s2api/s3api/ ???","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"f0159691dd6a26d734423b6053cc30bd71b43304","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"proxy-logging: create new field for s3_access_key_id"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Adding new field to be able to log the access key during the s2api"},{"line_number":10,"context_line":"calls. Also adding the minimal set of regression tests."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Signed-off-by: Vitaly Bordyug \u003cvbordug@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"da36a743_9ecbcab0","line":9,"in_reply_to":"98a4a536_050e89d6","updated":"2025-07-21 15:55:00.000000000","message":"Acknowledged","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0aa47ebcab4ef2dd9d3a2dc86b9dff7acaaf708e","unresolved":true,"context_lines":[{"line_number":7,"context_line":"proxy-logging: create new field for s3_access_key_id"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Added the new field to be able to log the access key during the s3api calls,"},{"line_number":10,"context_line":"consolidating self.environ modifications in the same place."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Since the logging patch added a new field to the log format, the policy index is"},{"line_number":13,"context_line":"now the second-to-last field instead of the last field."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"9433b1d1_f60c6fa1","line":10,"updated":"2025-07-21 17:42:51.000000000","message":"please wrap commit message body lines at 72 charcters per the openstack commit message guidelines:\n\nhttps://wiki.openstack.org/wiki/GitCommitMessages#Summary_of_Git_commit_message_structure","commit_id":"c459e27055fc82b410ad0e8045660c52fd9a1ab2"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"2ac35a9f7fdec54c065b9aacd74265d302dbda13","unresolved":false,"context_lines":[{"line_number":7,"context_line":"proxy-logging: create new field for s3_access_key_id"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Added the new field to be able to log the access key during the s3api calls,"},{"line_number":10,"context_line":"consolidating self.environ modifications in the same place."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Since the logging patch added a new field to the log format, the policy index is"},{"line_number":13,"context_line":"now the second-to-last field instead of the last field."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"2738f1e2_67a1d87e","line":10,"in_reply_to":"9433b1d1_f60c6fa1","updated":"2025-07-21 18:19:22.000000000","message":"Acknowledged","commit_id":"c459e27055fc82b410ad0e8045660c52fd9a1ab2"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"f0159691dd6a26d734423b6053cc30bd71b43304","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"6cff5c2c_31240dcc","updated":"2025-07-21 15:55:00.000000000","message":"Thanks Clay, I think I have addressed most of the concerns now. In case zuul is happy, this can be ready for another look.","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"65e7d250863f7d3b72c22e4d34d0c325b0d4ae2e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"cec37737_ab7a15b3","updated":"2025-07-16 19:42:31.000000000","message":"this is ... really good.  Likem sorry to have low expectations - but first time contributions rarely include reasonably written abstractions, detailed commit messages, docstrings and tests.  Maybe I have a low bar from lots of experience with open source but... I\u0027m impressed.\n\nPlease consider if the \"duplicated\" (???) AWS S3 auth header parsing in proxy-logging is absolutely *necessary* - the code base *generally tries* to take the convention of isolating domain knowledge between middlewares and components.  When we *have* to leak knowledge about a subsystem or middleware\u0027s implementation (like s3api, or slo, or the expirer, or symlinks, or EC, or encyrption, etc) between compoents we TRY to put as much *domain knowledge* as possible as CLOSE as possible to the implementation of that domain/subsystem/mw with a well defined and well tested *interface* to transfer the minimal amount of interaction into other parts of the system in a re-usable way.\n\ni.e. \n\nAnywhere someone needs to get a wizbang-trinket out of the twiddly-object they call the \"clear_and_obvious_helper()\" function.\n\n*I* think it would be better if proxy-logging always logged the value of the \"swift.clear_and_obvious_data_exchange_key\" key as \"name_we_made_up_to_describe_this_exchange\" field and then we test:\n\na) no matter what you put in there proxy-loggging will log it (simple; near impossible to get wrong)\nb) given the kinds of request we care about s3api will put the value we want in the right place (probably mostly already tested dozens of places, just need to add the asserts in all the existing/interesting tests)\n\n... but their may be reasons to do it differently, e.g. some out-of-tree auth mw (e.g. nvsts) might want something *different* to go into the proxy-logging field and has to \"override\" what s3api sets by default (i.e. the fall back to parsing AWS headers in proxy-logging might be \"incorrect\" for some implementation of session token hadnling) and in that case: having an inline opinionated implementation in proxy-logging would make it harder to override; or at a minimum \"opt-in by default\" which may not be what we want.\n\nI think you\u0027re MOSTLY already there with `s3api.access_token`; as trivial as it may seem I\u0027d avoid the temptation to do any more unless absolutely necessary.\n\nHonestly I\u0027m not sure I see any blocking issues (if zuul is happy); although it would be nice to make sure if we ARE adding a new interface (e.g. s3api.access_key) it works the way want.  I\u0027ll have to think about that and play with this functionally.  If you\u0027re sure the in-line header parsing is *needed* - I\u0027d appreciate if you could describe that requirement to allievate my distaste for bleeding s3api specific domain knowledge into proxy-logging and my *still* suggest it\u0027d look better as a helper over in common.middleware.s3api.utils","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0aa47ebcab4ef2dd9d3a2dc86b9dff7acaaf708e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"64b0a463_e6b185f1","updated":"2025-07-21 17:42:51.000000000","message":"this is probably fine\n\nwe could potentially debate if this field should be appended to the default log_msg_template\n\nDocs should also be updated:\n\nhttps://github.com/NVIDIA/swift/blob/master/doc/source/logs.rst\n\nI think the s3api test fixes would look better if they also asserted the value of the s3_access_key_id - e.g. it might be interesting if it\u0027s not set for some unexpected reason; but it looks like they are the expected `test:tester` from headers:\n\n```\n\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,\n```","commit_id":"c459e27055fc82b410ad0e8045660c52fd9a1ab2"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"98726e2b7a7699e15fe4e46e5ef29ac678b2d371","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"fa65e9e9_508a5695","updated":"2025-07-21 19:54:27.000000000","message":"I love that we should finally have a clear way to differentiate swift vs s3api requests in logs!\n\nI wonder if we might want to use `StrAnonymizer` or *maybe* `obscure_sensitive` on the new field, though. On the one hand, we don\u0027t currently register `AWSAccessKeyId` or `X-Amz-Credential` as sensitive params -- but we *do* register `Authorization` as a sensitive header, and anyone that\u0027s concerned about GDPR (say) would probably already be anonymizing the path-with-query...","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"924a7256f9454bc5cdb75824c2b566bd01b6ea18","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"04c347d9_e9523546","updated":"2025-07-22 06:59:51.000000000","message":"If anonymized, it needs to be reversible.","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"924a7256f9454bc5cdb75824c2b566bd01b6ea18","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"00443fc1_f02fa86c","in_reply_to":"fa65e9e9_508a5695","updated":"2025-07-22 06:59:51.000000000","message":"Primary objective is to differentiate tempauth like static keys with other ways of auth, while getting to an analog of username during the s3api req.","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"48cb23e50e05e5e63584d7ee1638db397f624669","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"dd8c9c58_b651557b","updated":"2025-07-23 20:37:38.000000000","message":"this is my fault - I did at one time suggest something like `s3api.access_key` - I hadn\u0027t realized how wrong that will look until I read it in the docs - mea culpa\n\nTBF I also at one time suggested:\n\n    swift.access_log_user_id\n\n^ which I *think* would be an improvement.  It\u0027s possible the name shouldn\u0027t be a blocker, it may be useful to get concensus or consider alternatives before the author changes it again.  However in general naming is important, specifically for operator facing configuration - however maybe less so than good explanatory prose which this change provides.\n\nThe `log_msg_template` option is also documented in `etc/proxy-server.conf-sample` - unfortunately both places should be updated to reflect the newly available option.  But maybe hold off until Tim tells us what to call it.","commit_id":"88ed87f437d1a9c57c854ace5b251f02db64f953"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"a1a96c3122ba9ee4958f0114043361279ce5cd59","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"a2e046b6_3cdc1377","updated":"2025-07-24 21:25:51.000000000","message":"The last edition should have all the comments addressed (unless I missed something)","commit_id":"b9e44be197f602d39b25427428e4bca38976b2b2"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6ee24158fd79c38981aec6b718f36b4a190c4bd7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"b019aa61_9cbfd9da","updated":"2025-08-06 22:50:10.000000000","message":"I have a concern that downstream auth middleware won\u0027t be able to override the value in the client req environ b/c they only get the to_swift_req environ\n\nbest case scenario this is something we can fix in a follow-up\nworst case scenario this interface isn\u0027t going to be helpful as-is without some work to allow re-ordering of auth \u0026 s3api mw in the pipeline","commit_id":"fbcbced18d5dc0d58046ddaa61980d251d0e3e12"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"67351b7740fc052e786aa27a298c2748c0e7b529","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"bc6d46f9_3c718d8c","updated":"2025-07-28 17:37:38.000000000","message":"just added respective lines to keystone and tempauth.","commit_id":"fbcbced18d5dc0d58046ddaa61980d251d0e3e12"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"527432dafe6c3edb79deca8832f101ae0a5bbbe7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"d9e0148c_609612b7","in_reply_to":"b019aa61_9cbfd9da","updated":"2025-08-07 16:14:24.000000000","message":"956804: use a mutable key | https://review.opendev.org/c/openstack/swift/+/956804 seems to be a possible solution for mw downstream of s3api to update s3 request access logging user_id.","commit_id":"fbcbced18d5dc0d58046ddaa61980d251d0e3e12"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"c785003f_17b8bab7","updated":"2025-08-11 19:53:51.000000000","message":"No blocking issues from me.  Seems like a reasonable interface to accomplish what it set out to - well implemented and sufficiently documented and tested.\n\nI wonder if the comment in the `doc/source/logs.rst` would be sufficient for documenting the mw interface, or if we should elaborate in the mw doc string:\n\nhttps://github.com/NVIDIA/swift/blob/master/swift/common/middleware/proxy_logging.py#L50\nhttps://docs.openstack.org/swift/latest/middleware.html#module-swift.common.middleware.proxy_logging\n\nIf the author respins I\u0027d like to see some test coverage for the tempauth change.","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"666064dd23044d190c1eca2bda0bd554e212b8b1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"dd4be91f_d7def97d","updated":"2025-08-11 20:08:29.000000000","message":"in addition the doc \u0026 comments to describe the mw interface\n\nmaybe useful to\n\na) unconditionally `setdefault(\u0027swift.access_log\u0027)` before `environ.copy()` in `to_swift_req`\nb) truncate the `access_key_id` before setting it as `user_id` to \"be helpful\"","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":16,"id":"f9ed2194_4aabd7ea","updated":"2025-08-18 19:22:44.000000000","message":"new respin should have all the fixes (again) - let me know if I missed something.","commit_id":"bb88aba8193ee370697701c8247d64f3ac994485"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"d9bbe1d84b5e811caa8809b9fb75652c463044b1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":18,"id":"95a08648_db6adc99","updated":"2025-08-19 19:32:00.000000000","message":"the changes LGTM. Tested this change with an out-of-tree auth middleware that supports s3api:\n\nlocalhost proxy-server: 127.0.0.1 127.0.0.1 19/Aug/2025/19/13/01 GET / HTTP/1.0 200 - aws-cli/1.32.13%20md/Botocore%231.34.13%20ua/2.0%20os/linux%235.15.0-142-generic%20md/arch%23x86_64%20lang/python%233.10.12%20md/pyimpl%23CPython%20cfg/retry-mode%23legacy%20botocore/1.34.13 - - 221 - txd60e689dbd834f3c99157-0068a4ccbd - 0.0229 - - 1755630781.232435703 1755630781.255322695 - team-nv-test","commit_id":"2e2f8a94c65b400eac38637dd31b9a678919fefb"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6061561d4c4ebe27bc17444426df3a3b25053e40","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"cd6965f4_d7885b64","updated":"2025-08-22 02:07:35.000000000","message":"As best I can tell this is correct.  It achieved what it set out to do based on the commit message and is sufficiently thorough in the attempt.\n\nswift tempauth log line:\n\n```\n2025-08-22T01:21:50.303904+00:00 saio proxy-server: 127.0.0.1 127.0.0.1 22/Aug/2025/01/21/50 HEAD /v1/AUTH_test%3Fformat%3Djson HTTP/1.0 204 - python-swiftclient-4.7.0.dev3 AUTH_tk406d1903c... - - - tx811fad45e31447e6a007c-0068a7c62e - 0.0215 - - 1755825710.282200813 1755825710.303704739 - test:tester\n```\n\ns3api log line:\n\n```\n2025-08-22T01:22:40.349592+00:00 saio proxy-server: 127.0.0.1 127.0.0.1 22/Aug/2025/01/22/40 GET / HTTP/1.0 200 - aws-cli/1.42.9%20md/Botocore%231.40.9%20ua/2.1%20os/linux%236.8.0-53-generic%20md/arch%23x86_64%20lang/python%233.12.3%20md/pyimpl%23CPython%20m/Z%2CD%2CC%2Cb%2CN%20cfg/retry-mode%23legacy%20botocore/1.40.9 - - 322 - txe6816ef33ac14bb793835-0068a7c660 - 0.0154 - - 1755825760.333989382 1755825760.349404573 - test:tester\n```\n\nI can also attest that as an integration point, NVIDIA was able to verify compatibility with two out-of-tree auth middlewares. I didn\u0027t verify the Keystone integration and recognize it\u0027s not tested - but it probably won\u0027t break anything. FLW.\n\nI\u0027ve found *some* S3API error responses (unrelated to auth) which are currently NOT setting `access_logging.user_id`, and I think they probably should (or could). However, as best I can tell, there are also going to be some auth parsing failure modes where we\u0027ll basically never be able to make a reasonable estimation of what the `access_logging.user_id` value should be, and other places where it\u0027d just be hard - so making it less likely to miss \"most\" error responses can be an area of ongoing improvement.\n\nI\u0027m holding off on +A mainly because I feel too close to the change. I\u0027d love to hear from Tim or Yan again that they agree this is ready to be maintained upstream. I\u0027m recommending NVIDIA carry this patch as-is.\n\nSome improvements we could follow up on (or squash) include:\n\n* Currently, auth middlewares are relying on either: 1) no one has done an `env.copy()` before their `setdefault` populates the field, or 2) whoever did `env.copy` did the `setdefault` *first*. S3API currently meets both of these requirements, but it feels like it\u0027s doing proxy_logging\u0027s job for it. Proxy-logging should set up the mutable field on the way in before anyone has a chance to mess it up.\n\n* The `doc/source/logs` is probably not the best place to describe how middleware authors should use `swift.access_logging`—that should be more for how ops should use the log lines. I think the best place to document proxy_logging middleware interfaces is in the module docstring, e.g., \"swift.log_info\" https://docs.openstack.org/swift/latest/middleware.html#module-swift.common.middleware.proxy_logging\n\n* Many error cases that happen in early S3Request validation can trivially be moved until *after* we\u0027ve set `swift.access_logging`. There\u0027s a lot going on in that `__init__` and a surprising number of existing tests that expect attempting to create an S3Request to raise an InvalidArgument exception/response. It seems to me S3API should endeavor to set the user_id when available, even for error responses.\n\n* The access_key_id truncation is very attractive to NVIDIA because we know we have an AWS STS \"compatible\" emulation that generates (ridiculously?) large access_key_ids due to an ecosystem of client tooling that lacked support for plumbing `aws_session_token`. I sort of doubt anyone else is in this boat, and we\u0027re actively taking steps to back ourselves out of the corner (by overriding a useful value in the new access_logging.user_id interface!). But also, it\u0027s (probably?) reasonable since S3API is going to fill in this new field for any out-of-tree S3-compatible auth middleware whether or not they asked for it - maybe do so somewhat conservatively? The only downside I can think of to the 128-character \"limit\" is if someone uses a prefix plus a SHA512 as their \"user_id\" and gets stuck with a rather unfortunate truncation. We *could* make the truncation behavior configurable, or even make S3API access_key_id -\u003e user_id population opt-in. I don\u0027t think any of that would be *harder* to add/change if we started with the conservative approach, though. The upside of the conservatively optimistic approach is all auth middlewares get more useful messages with no changes - but also no one gets surprised with a new default log_msg_template that drops 4K of access_key_id/session_token in their log lines! Regardless of what we ultimately decide to do, the behavior should be tested.\n\n^ I think most of these are addressed in my follow-up, so from my perspective they are not blockers:\n\n958251: sq? tests and docs | https://review.opendev.org/c/openstack/swift/+/958251","commit_id":"0c68af898666c71fa96ea36b0c9ef886a791808e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"2d32f8a7aa73d7f5c562b3ae0148ba7f93d47d9f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"c96dc8ce_427aff15","updated":"2025-08-25 04:07:28.000000000","message":"Maybe my -1 is more of a nit, but I think this will also be improved by Clay\u0027s follow up. So maybe we can squash that in too or land it at the same tiem.","commit_id":"0c68af898666c71fa96ea36b0c9ef886a791808e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"3a62edaa50e1d2648de7207a9e96eb2820ce8a44","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":20,"id":"e4cda262_629c4c40","updated":"2025-08-25 17:29:37.000000000","message":"Matt: please consider every change you ask an author to make (esp when they\u0027re in different timezones) come with some risk of slowing down getting helpful changes merged/shipped.\n\n\u003e However, for non-material grievances (nits) - you should feel confident in a positive review if the change is otherwise complete correct and undeniably makes Swift better (not perfect, better).\n\nhttps://docs.openstack.org/swift/latest/contributor/review_guidelines.html#scoring\n\nVitaly: please respin to remove the underscore from the call-site if you are able.","commit_id":"6c78b5474ea66e7585c95a525e95bf4a5f28d874"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3ce983c4df0fa7044cf844319ba5d9741ed1def7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":20,"id":"1031202b_1c037c8d","in_reply_to":"e4cda262_629c4c40","updated":"2025-08-26 01:15:09.000000000","message":"Yup, I understand, sorry. It was border line nit territory, although I did really want the function renamed for consistency and would\u0027ve had to do a follow up to fix it, so moved my nit needle to the please fix -1 zone 😊","commit_id":"6c78b5474ea66e7585c95a525e95bf4a5f28d874"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e451e938627eb96858478872511de705f1a0dfad","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"8f335b3c_33e964dd","updated":"2025-08-25 19:34:24.000000000","message":"this change should update the default value of log_msg_template in `etc/proxy-server.conf-sample`\n\n```\ndiff --git a/etc/proxy-server.conf-sample b/etc/proxy-server.conf-sample\nindex 0cfcf417b..701b514ac 100644\n--- a/etc/proxy-server.conf-sample\n+++ b/etc/proxy-server.conf-sample\n@@ -1103,7 +1103,7 @@ use \u003d egg:swift#proxy_logging\n # Template used to format access logs. All words surrounded by curly brackets\n # will be substituted with the appropriate values. For more information, see\n # https://docs.openstack.org/swift/latest/logs.html\n-# log_msg_template \u003d {client_ip} {remote_addr} {end_time.datetime} {method} {path} {protocol} {status_int} {referer} {user_agent} {auth_token} {bytes_recvd} {bytes_sent} {client_etag} {transaction_id} {headers} {request_time} {source} {log_info} {start_time} {end_time} {policy_index}\n+# log_msg_template \u003d {client_ip} {remote_addr} {end_time.datetime} {method} {path} {protocol} {status_int} {referer} {user_agent} {auth_token} {bytes_recvd} {bytes_sent} {client_etag} {transaction_id} {headers} {request_time} {source} {log_info} {start_time} {end_time} {policy_index} {access_user_id}\n \n # Note: Put before both ratelimit and auth in the pipeline.\n [filter:bulk]\n```\n\n\u003e New config options should be documented in example configs\n\u003e If a change includes incorrect or misleading documentation or is contrary to existing documentation is probably is not suitable to merge.\n\nhttps://docs.openstack.org/swift/latest/contributor/review_guidelines.html#documentation\n\ndunno why I missed that originally; mea culpa.","commit_id":"ebf8cb7b64e3fcaca6996fb2e6ae58fd1ffa430d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"41b61190a6c830af78bfc90f69d66f54e410a13f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":22,"id":"2b1a2b2d_685d9627","updated":"2025-08-25 20:40:35.000000000","message":"I\u0027ll try to sync up with Matt to get the +A\n\nI think this turned out great.  Kudos Vitaly.","commit_id":"1675412343fac14bd18f26909e0d700eac6ecb4d"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"b9fccbd72761539d6cf1b2872f3b32e588ef497a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":22,"id":"f2efa972_34232eb8","updated":"2025-08-25 19:45:40.000000000","message":"good  catch, fixed now.","commit_id":"1675412343fac14bd18f26909e0d700eac6ecb4d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"2bd1d5fcbb9796dd28318c2be4a7081032cfb239","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":23,"id":"384d846c_b200368c","updated":"2025-08-26 01:18:49.000000000","message":"Just fixed a type in the doc, +A\u0027ing based on Clay\u0027s previous +2","commit_id":"32eaab20b1799807995ce5edc0d7c99355d0aa61"}],"doc/source/logs.rst":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"48cb23e50e05e5e63584d7ee1638db397f624669","unresolved":true,"context_lines":[{"line_number":101,"context_line":"                         the logged response code if there was an error during the"},{"line_number":102,"context_line":"                         body of the request or a disconnect."},{"line_number":103,"context_line":"proxy_logging_access_key The access key for logging. Middlewares may set this field"},{"line_number":104,"context_line":"                         to identify the user for logging purposes. For S3 API"},{"line_number":105,"context_line":"                         requests, this contains the S3 access key ID. Other auth"},{"line_number":106,"context_line":"                         middlewares may set user-specific identifiers. For requests"},{"line_number":107,"context_line":"                         without auth middleware support, this field will be \"-\"."}],"source_content_type":"text/x-rst","patch_set":10,"id":"3fdb9658_fdb672cf","line":104,"updated":"2025-07-23 20:37:38.000000000","message":"I think there\u0027s a weird disconnect between \"access_key\" and \"user identity\" for loggin purposes.\n\nLike \"we should log the access key\" - sounds on the surface like the most brain dead security violation anyone could possibly concieve.\n\nWhile \"we should log the user id\" - sounds like the most rational and reasonable thing you could have in access logs.\n\nI think AWS was always weird to call it the \"access_key_ID\" where the \"ID\" part is doing the heaving lifting - i.e. it\u0027s NOT the \"access_key\" (that\u0027s the \"secret\") it\u0027s just the *ID* of that access_key.  In practice it\u0027s \"mostly\" the IAM user, but in lots of other cases it\u0027s a more complex id that scoped to just the specific set of temporary/service creds.\n\nFor our purpose I think it\u0027s best to just call it \"user_id\" or \"access_id\"\n\nI think we should avoid the term \"key\" and certainly not without clarifying \"key_id\"","commit_id":"88ed87f437d1a9c57c854ace5b251f02db64f953"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"a1a96c3122ba9ee4958f0114043361279ce5cd59","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                         the logged response code if there was an error during the"},{"line_number":102,"context_line":"                         body of the request or a disconnect."},{"line_number":103,"context_line":"proxy_logging_access_key The access key for logging. Middlewares may set this field"},{"line_number":104,"context_line":"                         to identify the user for logging purposes. For S3 API"},{"line_number":105,"context_line":"                         requests, this contains the S3 access key ID. Other auth"},{"line_number":106,"context_line":"                         middlewares may set user-specific identifiers. For requests"},{"line_number":107,"context_line":"                         without auth middleware support, this field will be \"-\"."}],"source_content_type":"text/x-rst","patch_set":10,"id":"80609018_14aa5216","line":104,"in_reply_to":"3fdb9658_fdb672cf","updated":"2025-07-24 21:25:51.000000000","message":"Done","commit_id":"88ed87f437d1a9c57c854ace5b251f02db64f953"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4eb47bcea58948081fbda03a091019566b7cde49","unresolved":true,"context_lines":[{"line_number":102,"context_line":"                    body of the request or a disconnect."},{"line_number":103,"context_line":"access_user_id      The user ID for logging. Middlewares may set this field"},{"line_number":104,"context_line":"                    to identify the user for logging purposes. For S3 API"},{"line_number":105,"context_line":"                    requests, this contains the S3 access key ID. Other auth"},{"line_number":106,"context_line":"                    middlewares may set user-specific identifiers. For requests"},{"line_number":107,"context_line":"                    without auth middleware support, this field will be \"-\"."},{"line_number":108,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":12,"id":"de0e12b2_4828626f","line":105,"range":{"start_line":105,"start_character":35,"end_line":105,"end_character":43},"updated":"2025-07-28 16:26:37.000000000","message":"\"defaults to\", yeah? Auth middleware is free to tweak that if/as needed.","commit_id":"029907b374456f27b7bf9c4eb8bd8c53f5a17404"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"aa402b54e69b44c723bf48101381746356e4d325","unresolved":false,"context_lines":[{"line_number":102,"context_line":"                    body of the request or a disconnect."},{"line_number":103,"context_line":"access_user_id      The user ID for logging. Middlewares may set this field"},{"line_number":104,"context_line":"                    to identify the user for logging purposes. For S3 API"},{"line_number":105,"context_line":"                    requests, this contains the S3 access key ID. Other auth"},{"line_number":106,"context_line":"                    middlewares may set user-specific identifiers. For requests"},{"line_number":107,"context_line":"                    without auth middleware support, this field will be \"-\"."},{"line_number":108,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":12,"id":"20b6732e_3f710d1a","line":105,"range":{"start_line":105,"start_character":35,"end_line":105,"end_character":43},"in_reply_to":"de0e12b2_4828626f","updated":"2025-07-28 16:31:44.000000000","message":"Acknowledged","commit_id":"029907b374456f27b7bf9c4eb8bd8c53f5a17404"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4eb47bcea58948081fbda03a091019566b7cde49","unresolved":true,"context_lines":[{"line_number":102,"context_line":"                    body of the request or a disconnect."},{"line_number":103,"context_line":"access_user_id      The user ID for logging. Middlewares may set this field"},{"line_number":104,"context_line":"                    to identify the user for logging purposes. For S3 API"},{"line_number":105,"context_line":"                    requests, this contains the S3 access key ID. Other auth"},{"line_number":106,"context_line":"                    middlewares may set user-specific identifiers. For requests"},{"line_number":107,"context_line":"                    without auth middleware support, this field will be \"-\"."},{"line_number":108,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":109,"context_line":""}],"source_content_type":"text/x-rst","patch_set":12,"id":"19072f9b_df4aaf38","line":106,"range":{"start_line":105,"start_character":66,"end_line":106,"end_character":66},"updated":"2025-07-28 16:26:37.000000000","message":"Do we want to say that auth middlewares generally *should* set this? If so, we should probably update tempauth (and likely keystoneauth), too. If not, I\u0027m not sure it should go into the default log format.","commit_id":"029907b374456f27b7bf9c4eb8bd8c53f5a17404"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"aa402b54e69b44c723bf48101381746356e4d325","unresolved":true,"context_lines":[{"line_number":102,"context_line":"                    body of the request or a disconnect."},{"line_number":103,"context_line":"access_user_id      The user ID for logging. Middlewares may set this field"},{"line_number":104,"context_line":"                    to identify the user for logging purposes. For S3 API"},{"line_number":105,"context_line":"                    requests, this contains the S3 access key ID. Other auth"},{"line_number":106,"context_line":"                    middlewares may set user-specific identifiers. For requests"},{"line_number":107,"context_line":"                    without auth middleware support, this field will be \"-\"."},{"line_number":108,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":109,"context_line":""}],"source_content_type":"text/x-rst","patch_set":12,"id":"72520f98_a8bc07e5","line":106,"range":{"start_line":105,"start_character":66,"end_line":106,"end_character":66},"in_reply_to":"19072f9b_df4aaf38","updated":"2025-07-28 16:31:44.000000000","message":"I believe it should, that is whole point of keeping track of the user accessing stuff. However some the concept of username might not apply to some middlewares. Id does however apply to tempauth (where I think I will add some bits too) - but it would remain up to the middleware if it \"wants\" to log the field.","commit_id":"029907b374456f27b7bf9c4eb8bd8c53f5a17404"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"67351b7740fc052e786aa27a298c2748c0e7b529","unresolved":false,"context_lines":[{"line_number":102,"context_line":"                    body of the request or a disconnect."},{"line_number":103,"context_line":"access_user_id      The user ID for logging. Middlewares may set this field"},{"line_number":104,"context_line":"                    to identify the user for logging purposes. For S3 API"},{"line_number":105,"context_line":"                    requests, this contains the S3 access key ID. Other auth"},{"line_number":106,"context_line":"                    middlewares may set user-specific identifiers. For requests"},{"line_number":107,"context_line":"                    without auth middleware support, this field will be \"-\"."},{"line_number":108,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":109,"context_line":""}],"source_content_type":"text/x-rst","patch_set":12,"id":"d88105ad_8a12b3ee","line":106,"range":{"start_line":105,"start_character":66,"end_line":106,"end_character":66},"in_reply_to":"72520f98_a8bc07e5","updated":"2025-07-28 17:37:38.000000000","message":"Done","commit_id":"029907b374456f27b7bf9c4eb8bd8c53f5a17404"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":101,"context_line":"                    the logged response code if there was an error during the"},{"line_number":102,"context_line":"                    body of the request or a disconnect."},{"line_number":103,"context_line":"access_user_id      The user ID for logging. Middlewares should set this field"},{"line_number":104,"context_line":"                    to identify the user for logging purposes. For S3 API"},{"line_number":105,"context_line":"                    requests, this contains the S3 access key ID. Other auth"},{"line_number":106,"context_line":"                    middlewares should set user-specific identifiers. For requests"},{"line_number":107,"context_line":"                    without auth middleware support, this field will be \"-\"."}],"source_content_type":"text/x-rst","patch_set":15,"id":"7f9c57b7_a185c91e","line":104,"updated":"2025-08-11 19:53:51.000000000","message":"perhaps \"mw should set `environ[\u0027swift.access_logging\u0027][\u0027user_id\u0027]` to identify ...`","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                    the logged response code if there was an error during the"},{"line_number":102,"context_line":"                    body of the request or a disconnect."},{"line_number":103,"context_line":"access_user_id      The user ID for logging. Middlewares should set this field"},{"line_number":104,"context_line":"                    to identify the user for logging purposes. For S3 API"},{"line_number":105,"context_line":"                    requests, this contains the S3 access key ID. Other auth"},{"line_number":106,"context_line":"                    middlewares should set user-specific identifiers. For requests"},{"line_number":107,"context_line":"                    without auth middleware support, this field will be \"-\"."}],"source_content_type":"text/x-rst","patch_set":15,"id":"f7570932_b387338a","line":104,"in_reply_to":"7f9c57b7_a185c91e","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"}],"swift/common/middleware/keystoneauth.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":224,"context_line":"                access_logging \u003d environ.setdefault(\u0027swift.access_logging\u0027, {})"},{"line_number":225,"context_line":"                access_logging[\u0027user_id\u0027] \u003d user_id"},{"line_number":226,"context_line":"            elif user_name:"},{"line_number":227,"context_line":"                access_logging \u003d environ.setdefault(\u0027swift.access_logging\u0027, {})"},{"line_number":228,"context_line":"                access_logging[\u0027user_id\u0027] \u003d user_name"},{"line_number":229,"context_line":"        else:"},{"line_number":230,"context_line":"            self.logger.debug(\u0027Authorizing as anonymous\u0027)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ef30c017_e79d8624","line":227,"updated":"2025-08-11 19:53:51.000000000","message":"probably clearer to DRY out L224 \u0026 L227\n\n```\n            access_logging \u003d environ.setdefault(\u0027swift.access_logging\u0027, {})\n            user_id, user_name \u003d env_identity.get(\u0027user\u0027, (None, None))\n            access_logging[\u0027user_id\u0027] \u003d user_id or user_name\n```\n\nFWIW there\u0027s tests that seem to cover both:\n\n```\n(Pdb) !env_identity\n{\u0027user\u0027: (\u002742\u0027, \u0027usr\u0027), ...\n```\n\nAND\n\n```\n(Pdb) !env_identity\n{\u0027user\u0027: (None, None), ...\n```\n\nbut I didn\u0027t see any for `user_name and not user_id` - so i\u0027m not sure how common/reasonable that is...","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":224,"context_line":"                access_logging \u003d environ.setdefault(\u0027swift.access_logging\u0027, {})"},{"line_number":225,"context_line":"                access_logging[\u0027user_id\u0027] \u003d user_id"},{"line_number":226,"context_line":"            elif user_name:"},{"line_number":227,"context_line":"                access_logging \u003d environ.setdefault(\u0027swift.access_logging\u0027, {})"},{"line_number":228,"context_line":"                access_logging[\u0027user_id\u0027] \u003d user_name"},{"line_number":229,"context_line":"        else:"},{"line_number":230,"context_line":"            self.logger.debug(\u0027Authorizing as anonymous\u0027)"}],"source_content_type":"text/x-python","patch_set":15,"id":"29638695_ecfc1afa","line":227,"in_reply_to":"ef30c017_e79d8624","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"}],"swift/common/middleware/proxy_logging.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"65e7d250863f7d3b72c22e4d34d0c325b0d4ae2e","unresolved":true,"context_lines":[{"line_number":257,"context_line":"        \"\"\""},{"line_number":258,"context_line":"        # Try to get from s3api.access_key set by S3 middleware"},{"line_number":259,"context_line":"        access_key \u003d req.environ.get(\u0027s3api.access_key\u0027)"},{"line_number":260,"context_line":"        if access_key:"},{"line_number":261,"context_line":"            return access_key"},{"line_number":262,"context_line":"        "},{"line_number":263,"context_line":"        # Parse from Authorization header for AWS4-HMAC-SHA256"}],"source_content_type":"text/x-python","patch_set":2,"id":"a487eb3c_70e59fc4","line":260,"updated":"2025-07-16 19:42:31.000000000","message":"when I was looking at the structure of the existing s3api auth call back environ keys I came up with a different way to spell this:\n\n951903: fallback to s3api access_key as auth_token | https://review.opendev.org/c/openstack/swift/+/951903\n\n`\u0027s3api.auth_details\u0027.get(\u0027access_key)`\n\ndoes this patch *add* the new `s3api.access_key` or is it pre-existing and I just missed it?","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"f0159691dd6a26d734423b6053cc30bd71b43304","unresolved":false,"context_lines":[{"line_number":257,"context_line":"        \"\"\""},{"line_number":258,"context_line":"        # Try to get from s3api.access_key set by S3 middleware"},{"line_number":259,"context_line":"        access_key \u003d req.environ.get(\u0027s3api.access_key\u0027)"},{"line_number":260,"context_line":"        if access_key:"},{"line_number":261,"context_line":"            return access_key"},{"line_number":262,"context_line":"        "},{"line_number":263,"context_line":"        # Parse from Authorization header for AWS4-HMAC-SHA256"}],"source_content_type":"text/x-python","patch_set":2,"id":"211fc281_ec6867e3","line":260,"in_reply_to":"a487eb3c_70e59fc4","updated":"2025-07-21 15:55:00.000000000","message":"was a new var for simplicity, now optimized out","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"65e7d250863f7d3b72c22e4d34d0c325b0d4ae2e","unresolved":true,"context_lines":[{"line_number":268,"context_line":"                access_key \u003d cred_part.split(\u0027/\u0027)[0]"},{"line_number":269,"context_line":"                return access_key"},{"line_number":270,"context_line":"            except (IndexError, AttributeError):"},{"line_number":271,"context_line":"                pass"},{"line_number":272,"context_line":"        "},{"line_number":273,"context_line":"        # Parse from Authorization header for AWS (v2 signature)"},{"line_number":274,"context_line":"        if auth_header.startswith(\u0027AWS \u0027):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9edb59d1_a17fc8bb","line":271,"updated":"2025-07-16 19:42:31.000000000","message":"this should be unnecessary if we\u0027re leveraging the correct structure to pass domain knowledge between middlewares.  It also adds what should be s3api specific knowledge into the proxy-logging mw in a way that increases mainteance burden and violates DRY.\n\nImagine a scenario where there\u0027s a change \"add v5 signatures to s3api\" - presumably that will learn how to parse a new Authorization header and break it down into coponents maybe instead of `Credential\u003d` AWS has their sdks send `AWS_USER_ID\u003d` or something - we don\u0027t want to have a commit later \"and also add v5 support to proxy logging\"\n\n... better if s3api handles all the s3api things and writes the value that it wants proxy-logging to use in the `s3_access_key_id` field into a well-known location in the request environ and proxy-logging will use that unmolested from in the environ if it\u0027s available.   With this seperation of concerns if proxy-logging gets the wrong value, or the value is missing - that\u0027s an s3api bug.","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"f0159691dd6a26d734423b6053cc30bd71b43304","unresolved":false,"context_lines":[{"line_number":268,"context_line":"                access_key \u003d cred_part.split(\u0027/\u0027)[0]"},{"line_number":269,"context_line":"                return access_key"},{"line_number":270,"context_line":"            except (IndexError, AttributeError):"},{"line_number":271,"context_line":"                pass"},{"line_number":272,"context_line":"        "},{"line_number":273,"context_line":"        # Parse from Authorization header for AWS (v2 signature)"},{"line_number":274,"context_line":"        if auth_header.startswith(\u0027AWS \u0027):"}],"source_content_type":"text/x-python","patch_set":2,"id":"d39e8e6a_b610d228","line":271,"in_reply_to":"9edb59d1_a17fc8bb","updated":"2025-07-21 15:55:00.000000000","message":"Acknowledged","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"65e7d250863f7d3b72c22e4d34d0c325b0d4ae2e","unresolved":true,"context_lines":[{"line_number":276,"context_line":"                access_key \u003d auth_header.split(\u0027AWS \u0027)[1].split(\u0027:\u0027)[0]"},{"line_number":277,"context_line":"                return access_key"},{"line_number":278,"context_line":"            except (IndexError, AttributeError):"},{"line_number":279,"context_line":"                pass"},{"line_number":280,"context_line":"        "},{"line_number":281,"context_line":"        return \u0027-\u0027"},{"line_number":282,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"41ae7d83_06ce3d16","line":279,"updated":"2025-07-16 19:42:31.000000000","message":"not ideal for proxy logging to have to know all this stuff about s3api - better if this was a helper in s3api OR if proxy-logging just pulled this information from the request environ.","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"f0159691dd6a26d734423b6053cc30bd71b43304","unresolved":false,"context_lines":[{"line_number":276,"context_line":"                access_key \u003d auth_header.split(\u0027AWS \u0027)[1].split(\u0027:\u0027)[0]"},{"line_number":277,"context_line":"                return access_key"},{"line_number":278,"context_line":"            except (IndexError, AttributeError):"},{"line_number":279,"context_line":"                pass"},{"line_number":280,"context_line":"        "},{"line_number":281,"context_line":"        return \u0027-\u0027"},{"line_number":282,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"69c4441a_3e1cd4d7","line":279,"in_reply_to":"41ae7d83_06ce3d16","updated":"2025-07-21 15:55:00.000000000","message":"Done","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"65e7d250863f7d3b72c22e4d34d0c325b0d4ae2e","unresolved":true,"context_lines":[{"line_number":367,"context_line":"            \u0027ttfb\u0027: ttfb,"},{"line_number":368,"context_line":"            \u0027pid\u0027: self.pid,"},{"line_number":369,"context_line":"            \u0027wire_status_int\u0027: wire_status_int or status_int,"},{"line_number":370,"context_line":"            \u0027s3_access_key_id\u0027: self._get_s3_access_key_id(req),"},{"line_number":371,"context_line":"        }"},{"line_number":372,"context_line":"        self.access_logger.info("},{"line_number":373,"context_line":"            self.log_formatter.format(self.log_msg_template,"}],"source_content_type":"text/x-python","patch_set":2,"id":"aa63ba93_2e854053","line":370,"updated":"2025-07-16 19:42:31.000000000","message":"this this is called after the response and body have fully iterated s3api would have had ample time to set the correct `s3_access_key_id` value in the \"correct\" location in the request environ.","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"f0159691dd6a26d734423b6053cc30bd71b43304","unresolved":false,"context_lines":[{"line_number":367,"context_line":"            \u0027ttfb\u0027: ttfb,"},{"line_number":368,"context_line":"            \u0027pid\u0027: self.pid,"},{"line_number":369,"context_line":"            \u0027wire_status_int\u0027: wire_status_int or status_int,"},{"line_number":370,"context_line":"            \u0027s3_access_key_id\u0027: self._get_s3_access_key_id(req),"},{"line_number":371,"context_line":"        }"},{"line_number":372,"context_line":"        self.access_logger.info("},{"line_number":373,"context_line":"            self.log_formatter.format(self.log_msg_template,"}],"source_content_type":"text/x-python","patch_set":2,"id":"ec4f8746_96e8b301","line":370,"in_reply_to":"aa63ba93_2e854053","updated":"2025-07-21 15:55:00.000000000","message":"Acknowledged","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0aa47ebcab4ef2dd9d3a2dc86b9dff7acaaf708e","unresolved":true,"context_lines":[{"line_number":121,"context_line":"                \u0027{auth_token} {bytes_recvd} {bytes_sent} {client_etag} \u0027"},{"line_number":122,"context_line":"                \u0027{transaction_id} {headers} {request_time} {source} \u0027"},{"line_number":123,"context_line":"                \u0027{log_info} {start_time} {end_time} {policy_index} \u0027"},{"line_number":124,"context_line":"                \u0027{s3_access_key_id}\u0027))"},{"line_number":125,"context_line":"        # The salt is only used in StrAnonymizer. This class requires bytes,"},{"line_number":126,"context_line":"        # convert it now to prevent useless convertion later."},{"line_number":127,"context_line":"        self.anonymization_method \u003d conf.get(\u0027log_anonymization_method\u0027, \u0027md5\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"2b89adf7_b0508312","line":124,"updated":"2025-07-21 17:42:51.000000000","message":"ah, perhaps don\u0027t change the default and then you don\u0027t have to fix the s3api tests\n\nof course... it would be even better if some of the s3api tests asserted on the value of the s3_access_key_id - so in that case maybe it\u0027s convenient to change the default log_msg_template\n\nsince we have this option configured explicitly in prod it\u0027s still \"default off\" for us - which is best.","commit_id":"c459e27055fc82b410ad0e8045660c52fd9a1ab2"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"2ac35a9f7fdec54c065b9aacd74265d302dbda13","unresolved":false,"context_lines":[{"line_number":121,"context_line":"                \u0027{auth_token} {bytes_recvd} {bytes_sent} {client_etag} \u0027"},{"line_number":122,"context_line":"                \u0027{transaction_id} {headers} {request_time} {source} \u0027"},{"line_number":123,"context_line":"                \u0027{log_info} {start_time} {end_time} {policy_index} \u0027"},{"line_number":124,"context_line":"                \u0027{s3_access_key_id}\u0027))"},{"line_number":125,"context_line":"        # The salt is only used in StrAnonymizer. This class requires bytes,"},{"line_number":126,"context_line":"        # convert it now to prevent useless convertion later."},{"line_number":127,"context_line":"        self.anonymization_method \u003d conf.get(\u0027log_anonymization_method\u0027, \u0027md5\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"551692d2_e4a9ca08","line":124,"in_reply_to":"2b89adf7_b0508312","updated":"2025-07-21 18:19:22.000000000","message":"Added the asserts as I think it makes sense to always have that field present (and logged, eventually in some tersely formatted way).","commit_id":"c459e27055fc82b410ad0e8045660c52fd9a1ab2"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"98726e2b7a7699e15fe4e46e5ef29ac678b2d371","unresolved":true,"context_lines":[{"line_number":256,"context_line":"        :returns: S3 access key ID if available, \u0027-\u0027 otherwise"},{"line_number":257,"context_line":"        \"\"\""},{"line_number":258,"context_line":"        auth_details \u003d req.environ.get(\u0027s3api.auth_details\u0027, {})"},{"line_number":259,"context_line":"        return auth_details.get(\u0027access_key\u0027, \u0027-\u0027)"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def log_request(self, req, status_int, bytes_received, bytes_sent,"},{"line_number":262,"context_line":"                    start_time, end_time, resp_headers\u003dNone, ttfb\u003d0,"}],"source_content_type":"text/x-python","patch_set":6,"id":"0d383ff4_a1f92260","line":259,"range":{"start_line":259,"start_character":15,"end_line":259,"end_character":50},"updated":"2025-07-21 19:54:27.000000000","message":"This can just be `auth_details.get(\u0027access_key\u0027)`, yeah? The `LogStringFormatter` should take care of translating `None` to `\u0027-\u0027`, just as it does with other fields.","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"924a7256f9454bc5cdb75824c2b566bd01b6ea18","unresolved":true,"context_lines":[{"line_number":256,"context_line":"        :returns: S3 access key ID if available, \u0027-\u0027 otherwise"},{"line_number":257,"context_line":"        \"\"\""},{"line_number":258,"context_line":"        auth_details \u003d req.environ.get(\u0027s3api.auth_details\u0027, {})"},{"line_number":259,"context_line":"        return auth_details.get(\u0027access_key\u0027, \u0027-\u0027)"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def log_request(self, req, status_int, bytes_received, bytes_sent,"},{"line_number":262,"context_line":"                    start_time, end_time, resp_headers\u003dNone, ttfb\u003d0,"}],"source_content_type":"text/x-python","patch_set":6,"id":"c27efd3f_6bb5f07e","line":259,"range":{"start_line":259,"start_character":15,"end_line":259,"end_character":50},"in_reply_to":"0d383ff4_a1f92260","updated":"2025-07-22 06:59:51.000000000","message":"correct, and unit tests should catch if it would stop doing so. Will fix.","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"a1a96c3122ba9ee4958f0114043361279ce5cd59","unresolved":false,"context_lines":[{"line_number":256,"context_line":"        :returns: S3 access key ID if available, \u0027-\u0027 otherwise"},{"line_number":257,"context_line":"        \"\"\""},{"line_number":258,"context_line":"        auth_details \u003d req.environ.get(\u0027s3api.auth_details\u0027, {})"},{"line_number":259,"context_line":"        return auth_details.get(\u0027access_key\u0027, \u0027-\u0027)"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"    def log_request(self, req, status_int, bytes_received, bytes_sent,"},{"line_number":262,"context_line":"                    start_time, end_time, resp_headers\u003dNone, ttfb\u003d0,"}],"source_content_type":"text/x-python","patch_set":6,"id":"36689777_7f7e0dbe","line":259,"range":{"start_line":259,"start_character":15,"end_line":259,"end_character":50},"in_reply_to":"c27efd3f_6bb5f07e","updated":"2025-07-24 21:25:51.000000000","message":"Done","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"98726e2b7a7699e15fe4e46e5ef29ac678b2d371","unresolved":true,"context_lines":[{"line_number":345,"context_line":"            \u0027ttfb\u0027: ttfb,"},{"line_number":346,"context_line":"            \u0027pid\u0027: self.pid,"},{"line_number":347,"context_line":"            \u0027wire_status_int\u0027: wire_status_int or status_int,"},{"line_number":348,"context_line":"            \u0027s3_access_key_id\u0027: self._get_s3_access_key_id(req),"},{"line_number":349,"context_line":"        }"},{"line_number":350,"context_line":"        self.access_logger.info("},{"line_number":351,"context_line":"            self.log_formatter.format(self.log_msg_template,"}],"source_content_type":"text/x-python","patch_set":6,"id":"5db35920_a0d1e70d","line":348,"updated":"2025-07-21 19:54:27.000000000","message":"Should this get a `StrAnonymizer` like `client_ip` and `user_agent`? Seems like it ought to be roughly as sensitive...","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4ce8f6da4b152c717bee82ea74b90ebe31e56cd3","unresolved":true,"context_lines":[{"line_number":345,"context_line":"            \u0027ttfb\u0027: ttfb,"},{"line_number":346,"context_line":"            \u0027pid\u0027: self.pid,"},{"line_number":347,"context_line":"            \u0027wire_status_int\u0027: wire_status_int or status_int,"},{"line_number":348,"context_line":"            \u0027s3_access_key_id\u0027: self._get_s3_access_key_id(req),"},{"line_number":349,"context_line":"        }"},{"line_number":350,"context_line":"        self.access_logger.info("},{"line_number":351,"context_line":"            self.log_formatter.format(self.log_msg_template,"}],"source_content_type":"text/x-python","patch_set":6,"id":"5dedf007_66a71446","line":348,"in_reply_to":"47b33434_fb953797","updated":"2025-07-23 19:39:15.000000000","message":"So the `StrAnonymizer` comes through in the clear by default; a `log_msg_template` with `{s3_access_key_id}` (or now, `{proxy_logging_access_key}`) would have that replaced by `test:tester` (for example) for s3api requests.\n\nThe trick is that the `StrAnonymizer` makes it *anonymizable*, so an operator could instead use `{proxy_logging_access_key.anonymized}` in their log template, and get something like `{MD5}bd61bae621a58ed47beb1f973071d68e`.","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"924a7256f9454bc5cdb75824c2b566bd01b6ea18","unresolved":true,"context_lines":[{"line_number":345,"context_line":"            \u0027ttfb\u0027: ttfb,"},{"line_number":346,"context_line":"            \u0027pid\u0027: self.pid,"},{"line_number":347,"context_line":"            \u0027wire_status_int\u0027: wire_status_int or status_int,"},{"line_number":348,"context_line":"            \u0027s3_access_key_id\u0027: self._get_s3_access_key_id(req),"},{"line_number":349,"context_line":"        }"},{"line_number":350,"context_line":"        self.access_logger.info("},{"line_number":351,"context_line":"            self.log_formatter.format(self.log_msg_template,"}],"source_content_type":"text/x-python","patch_set":6,"id":"47b33434_fb953797","line":348,"in_reply_to":"5db35920_a0d1e70d","updated":"2025-07-22 06:59:51.000000000","message":"Here, not quite, although I am not 100% sure what is the right way. Sure it is sensitive, but there should also be a way to search for the specific ip  or the specific user-agent or both ( like some totally smart script makes a DOS like load - there should be a way to quickly identify and disable that).\n\nif it is just about base64 for all the sensitive fields, it may work as well. However I would discuss the exact way to obfuscate after the information starts to be available. Will check what is done for the client_ip and if that can be reused anyway .","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"a1a96c3122ba9ee4958f0114043361279ce5cd59","unresolved":false,"context_lines":[{"line_number":345,"context_line":"            \u0027ttfb\u0027: ttfb,"},{"line_number":346,"context_line":"            \u0027pid\u0027: self.pid,"},{"line_number":347,"context_line":"            \u0027wire_status_int\u0027: wire_status_int or status_int,"},{"line_number":348,"context_line":"            \u0027s3_access_key_id\u0027: self._get_s3_access_key_id(req),"},{"line_number":349,"context_line":"        }"},{"line_number":350,"context_line":"        self.access_logger.info("},{"line_number":351,"context_line":"            self.log_formatter.format(self.log_msg_template,"}],"source_content_type":"text/x-python","patch_set":6,"id":"3e41fb99_bccbf715","line":348,"in_reply_to":"5dedf007_66a71446","updated":"2025-07-24 21:25:51.000000000","message":"In such a case I am fine to add that function.","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"48cb23e50e05e5e63584d7ee1638db397f624669","unresolved":true,"context_lines":[{"line_number":345,"context_line":"            \u0027ttfb\u0027: ttfb,"},{"line_number":346,"context_line":"            \u0027pid\u0027: self.pid,"},{"line_number":347,"context_line":"            \u0027wire_status_int\u0027: wire_status_int or status_int,"},{"line_number":348,"context_line":"            \u0027s3_access_key_id\u0027: self._get_s3_access_key_id(req),"},{"line_number":349,"context_line":"        }"},{"line_number":350,"context_line":"        self.access_logger.info("},{"line_number":351,"context_line":"            self.log_formatter.format(self.log_msg_template,"}],"source_content_type":"text/x-python","patch_set":6,"id":"31577834_a17be888","line":348,"in_reply_to":"5dedf007_66a71446","updated":"2025-07-23 20:37:38.000000000","message":"oh right, so 1) it\u0027s opt-in and 2) it\u0027s consistent 3) if you know what you\u0027re looking for you can pre-calculate the hash (there\u0027s some secret salt?) and know what you\u0027re looking at.\n\nThat\u0027s a neat feature - seems reasonable to support it out of the gate - but probably adds some testing burden.","commit_id":"99389788a4d810261dd45061fbbb4fb606f5d85f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":212,"context_line":"            \u0027pid\u0027: \u002742\u0027,"},{"line_number":213,"context_line":"            \u0027wire_status_int\u0027: \u0027200\u0027,"},{"line_number":214,"context_line":"            \u0027access_user_id\u0027: StrAnonymizer(\u0027AKIA1234567890123456\u0027,"},{"line_number":215,"context_line":"                                            self.anonymization_method,"},{"line_number":216,"context_line":"                                            self.anonymization_salt),"},{"line_number":217,"context_line":"        }"},{"line_number":218,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"b8e01ffb_da675d6b","line":215,"updated":"2025-08-11 19:53:51.000000000","message":"so... I guess the value of the \"data\" here for the \"replacements test\" doesn\u0027t *really* matter - but for e.g. `client_ip` the stub value used `1.2.3.4`\n\nso this might be better as just `example_user` or `AKIAIOSFODNN7EXAMPLE` so at least it shows up when you google:\n\nhttps://docs.aws.amazon.com/STS/latest/APIReference/API_GetAccessKeyInfo.html","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6061561d4c4ebe27bc17444426df3a3b25053e40","unresolved":false,"context_lines":[{"line_number":212,"context_line":"            \u0027pid\u0027: \u002742\u0027,"},{"line_number":213,"context_line":"            \u0027wire_status_int\u0027: \u0027200\u0027,"},{"line_number":214,"context_line":"            \u0027access_user_id\u0027: StrAnonymizer(\u0027AKIA1234567890123456\u0027,"},{"line_number":215,"context_line":"                                            self.anonymization_method,"},{"line_number":216,"context_line":"                                            self.anonymization_salt),"},{"line_number":217,"context_line":"        }"},{"line_number":218,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"4c589bcf_d1c77ed7","line":215,"in_reply_to":"b8e01ffb_da675d6b","updated":"2025-08-22 02:07:35.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"56cda9fb3edb189ac782572d4004e237520965d0","unresolved":false,"context_lines":[{"line_number":212,"context_line":"            \u0027pid\u0027: \u002742\u0027,"},{"line_number":213,"context_line":"            \u0027wire_status_int\u0027: \u0027200\u0027,"},{"line_number":214,"context_line":"            \u0027access_user_id\u0027: StrAnonymizer(\u0027AKIA1234567890123456\u0027,"},{"line_number":215,"context_line":"                                            self.anonymization_method,"},{"line_number":216,"context_line":"                                            self.anonymization_salt),"},{"line_number":217,"context_line":"        }"},{"line_number":218,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"d770e769_4d582fc9","line":215,"in_reply_to":"b8e01ffb_da675d6b","updated":"2025-08-25 15:23:41.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":257,"context_line":"        :param req: swob.Request object for the request"},{"line_number":258,"context_line":"        :returns: User ID for logging if available, None otherwise"},{"line_number":259,"context_line":"        \"\"\""},{"line_number":260,"context_line":"        return req.environ.get(\u0027swift.access_logging\u0027, {}).get(\u0027user_id\u0027)"},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"    def log_request(self, req, status_int, bytes_received, bytes_sent,"},{"line_number":263,"context_line":"                    start_time, end_time, resp_headers\u003dNone, ttfb\u003d0,"}],"source_content_type":"text/x-python","patch_set":15,"id":"cc6e4d55_0432ecc2","line":260,"updated":"2025-08-11 19:53:51.000000000","message":"I wonder if we should document somewhere that mw should set `env[\u0027swift.access_logging\u0027][\u0027user_id\u0027]` for this to work since `env[\u0027access_user_id\u0027]` will not.","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":257,"context_line":"        :param req: swob.Request object for the request"},{"line_number":258,"context_line":"        :returns: User ID for logging if available, None otherwise"},{"line_number":259,"context_line":"        \"\"\""},{"line_number":260,"context_line":"        return req.environ.get(\u0027swift.access_logging\u0027, {}).get(\u0027user_id\u0027)"},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"    def log_request(self, req, status_int, bytes_received, bytes_sent,"},{"line_number":263,"context_line":"                    start_time, end_time, resp_headers\u003dNone, ttfb\u003d0,"}],"source_content_type":"text/x-python","patch_set":15,"id":"7de3a99a_e91690f5","line":260,"in_reply_to":"cc6e4d55_0432ecc2","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6061561d4c4ebe27bc17444426df3a3b25053e40","unresolved":true,"context_lines":[{"line_number":53,"context_line":"  otherwise be detectable from the plain log information. Code that"},{"line_number":54,"context_line":"  wishes to add additional log information should use code like"},{"line_number":55,"context_line":"  ``env.setdefault(\u0027swift.log_info\u0027, []).append(your_info)`` so as to"},{"line_number":56,"context_line":"  not disturb others\u0027 log information."},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"* Values that are missing (e.g. due to a header not being present) or zero"},{"line_number":59,"context_line":"  are generally represented by a single hyphen (\u0027-\u0027)."}],"source_content_type":"text/x-python","patch_set":19,"id":"01447d45_973a643b","line":56,"updated":"2025-08-22 02:07:35.000000000","message":"this seems *really* similar to access_logging\n\n958251: sq? tests and docs | https://review.opendev.org/c/openstack/swift/+/958251","commit_id":"0c68af898666c71fa96ea36b0c9ef886a791808e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"2d32f8a7aa73d7f5c562b3ae0148ba7f93d47d9f","unresolved":true,"context_lines":[{"line_number":250,"context_line":"        if any_obscured:"},{"line_number":251,"context_line":"            req.params \u003d new_params"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    def _get_access_user_id(self, req):"},{"line_number":254,"context_line":"        \"\"\""},{"line_number":255,"context_line":"        Get access user ID from request environ."},{"line_number":256,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"c86bbd3e_0a3d7190","line":253,"updated":"2025-08-25 04:07:28.000000000","message":"Although this probably \"should\" be considered a private method and start with a \u0027_\u0027 none of the other \"get data out of request\" methods start with a \u0027_\u0027. So this shouldn\u0027t either.","commit_id":"0c68af898666c71fa96ea36b0c9ef886a791808e"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"56cda9fb3edb189ac782572d4004e237520965d0","unresolved":false,"context_lines":[{"line_number":250,"context_line":"        if any_obscured:"},{"line_number":251,"context_line":"            req.params \u003d new_params"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    def _get_access_user_id(self, req):"},{"line_number":254,"context_line":"        \"\"\""},{"line_number":255,"context_line":"        Get access user ID from request environ."},{"line_number":256,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"7a8c7763_04e6de87","line":253,"in_reply_to":"c86bbd3e_0a3d7190","updated":"2025-08-25 15:23:41.000000000","message":"Done","commit_id":"0c68af898666c71fa96ea36b0c9ef886a791808e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"3a62edaa50e1d2648de7207a9e96eb2820ce8a44","unresolved":true,"context_lines":[{"line_number":347,"context_line":"            \u0027pid\u0027: self.pid,"},{"line_number":348,"context_line":"            \u0027wire_status_int\u0027: wire_status_int or status_int,"},{"line_number":349,"context_line":"            \u0027access_user_id\u0027: StrAnonymizer("},{"line_number":350,"context_line":"                self._get_access_user_id(req), self.anonymization_method,"},{"line_number":351,"context_line":"                self.anonymization_salt),"},{"line_number":352,"context_line":"        }"},{"line_number":353,"context_line":"        self.access_logger.info("}],"source_content_type":"text/x-python","patch_set":20,"id":"f88a59c8_885c1c12","line":350,"updated":"2025-08-25 17:29:37.000000000","message":"womp womp:\n\n\n```\nAug 25 17:25:33 saio proxy-server: \u0027ProxyLoggingMiddleware\u0027 object has no attribute \u0027_get_access_user_id\u0027: \nTraceback (most recent call last):\n  File \"/vagrant/swift/swift/common/middleware/s3api/s3api.py\", line 351, in __call__\n    resp \u003d self.handle_request(req)\n  File \"/vagrant/swift/swift/common/middleware/s3api/s3api.py\", line 392, in handle_request\n    res \u003d handler(req)\n  File \"/vagrant/swift/swift/common/middleware/s3api/controllers/service.py\", line 35, in GET\n    resp \u003d req.get_response(self.app, query\u003d{\u0027format\u0027: \u0027json\u0027})\n  File \"/vagrant/swift/swift/common/middleware/s3api/s3request.py\", line 2272, in get_response\n    return self._get_response(app, method, container, obj,\n  File \"/vagrant/swift/swift/common/middleware/s3api/s3request.py\", line 2181, in _get_response\n    sw_resp \u003d sw_req.get_response(app)\n  File \"/vagrant/swift/swift/common/swob.py\", line 1115, in get_response\n    status, headers, app_iter \u003d self.call_application(application)\n  File \"/vagrant/swift/swift/common/swob.py\", line 1099, in call_application\n    app_iter \u003d application(self.environ, start_response)\n  File \"/vagrant/swift/swift/common/middleware/s3api/s3api.py\", line 196, in __call__\n    return self.app(env, start_response)\n  File \"/vagrant/.scratch/swiftstack-auth/swiftstack_auth/swiftstack_authen.py\", line 153, in __call__\n    return self.app(env, start_response)\n  File \"/vagrant/.scratch/swiftstack-auth/swiftstack_auth/swiftstack_authz.py\", line 434, in __call__\n    return self.app(env, start_response)\n  File \"/vagrant/.scratch/swiftstack-auth/swiftstack_auth/swiftstack_authz.py\", line 219, in __call__\n    return self.app(env, new_start_response)\n  File \"/vagrant/.scratch/nvsts-middleware/nvsts_middleware/nvsts_middleware.py\", line 464, in __call__\n    return resp(env, start_response)\n  File \"/vagrant/.scratch/nvsts-middleware/nvsts_middleware/nvauth_middleware.py\", line 286, in __call__\n    return self.app(env, start_response)\n  File \"/vagrant/swift/swift/common/middleware/ratelimit.py\", line 321, in __call__\n    return self.app(env, start_response)\n  File \"/vagrant/swift/swift/common/middleware/staticweb.py\", line 573, in __call__\n    return self.app(env, start_response)\n  File \"/vagrant/swift/swift/common/middleware/copy.py\", line 298, in __call__\n    return self.app(env, start_response)\n  File \"/vagrant/swift/swift/common/middleware/slo.py\", line 1861, in __call__\n    return self.app(env, start_response)\n  File \"/vagrant/swift/swift/common/middleware/dlo.py\", line 433, in __call__\n    return self.app(env, start_response)\n  File \"/vagrant/swift/swift/common/middleware/versioned_writes/legacy.py\", line 840, in __call__\n    return self.app(env, start_response)\n  File \"/vagrant/swift/swift/common/middleware/versioned_writes/object_versioning.py\", line 1473, in __call__\n    return self.account_request(req, api_version, account,\n  File \"/vagrant/swift/swift/common/middleware/versioned_writes/object_versioning.py\", line 1400, in account_request\n    return account_ctx.list_containers(\n  File \"/vagrant/swift/swift/common/middleware/versioned_writes/object_versioning.py\", line 1294, in list_containers\n    body \u003d b\u0027\u0027.join(app_resp)\n  File \"/vagrant/swift/swift/common/utils/__init__.py\", line 2446, in __next__\n    return self._get_next_item()\n  File \"/vagrant/swift/swift/common/utils/__init__.py\", line 2442, in _get_next_item\n    return next(self.wrapped_iter)\n  File \"/vagrant/swift/swift/common/middleware/proxy_logging.py\", line 542, in iter_response\n    self.log_request(\n  File \"/vagrant/swift/swift/common/middleware/proxy_logging.py\", line 350, in log_request\n    self._get_access_user_id(req), self.anonymization_method,\nAttributeError: \u0027ProxyLoggingMiddleware\u0027 object has no attribute \u0027_get_access_user_id\u0027 (txn: tx692ff12e4b9a46b988fe3-0068ac9c8d) (client_ip: 127.0.0.1)\n```","commit_id":"6c78b5474ea66e7585c95a525e95bf4a5f28d874"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3ce983c4df0fa7044cf844319ba5d9741ed1def7","unresolved":true,"context_lines":[{"line_number":74,"context_line":"logged by the rightmost middleware (with a ``swift.source`` set) and the"},{"line_number":75,"context_line":"outgoing request (with body overridden) will be logged by leftmost middleware."},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"Requests пуthat follow the normal pipeline (use the same wsgi environment"},{"line_number":78,"context_line":"throughout) will not be double logged because an environment variable"},{"line_number":79,"context_line":"(``swift.proxy_access_log_made``) is checked/set when a log is made."},{"line_number":80,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"ec0b24ba_21f6dcf9","line":77,"range":{"start_line":77,"start_character":9,"end_line":77,"end_character":11},"updated":"2025-08-26 01:15:09.000000000","message":"This probably shouldn\u0027t be there. I\u0027ll push up a patchset that changes this doc, then +A based on Clay\u0027s previous +2.","commit_id":"1675412343fac14bd18f26909e0d700eac6ecb4d"}],"swift/common/middleware/s3api/s3request.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"65e7d250863f7d3b72c22e4d34d0c325b0d4ae2e","unresolved":true,"context_lines":[{"line_number":1052,"context_line":"        self._timestamp \u003d None"},{"line_number":1053,"context_line":"        self.access_key, self.signature \u003d self._parse_auth_info()"},{"line_number":1054,"context_line":"        # Store access key in environment for proxy logging"},{"line_number":1055,"context_line":"        self.environ[\u0027s3api.access_key\u0027] \u003d self.access_key"},{"line_number":1056,"context_line":"        self.bucket_in_host \u003d self._parse_host()"},{"line_number":1057,"context_line":"        self.container_name, self.object_name \u003d self._parse_uri()"},{"line_number":1058,"context_line":"        self._validate_headers()"}],"source_content_type":"text/x-python","patch_set":2,"id":"ede2815d_e05b08b4","line":1055,"updated":"2025-07-16 19:42:31.000000000","message":"oic, it *is* a new variable.  presumably the env passed in here is the same request environ dict that proxy-logging is dealing with.\n\nIf I\u0027m reading the convention correctly, when s3api creates environ keys for communicating with *itself* it prefixes those with `s3api` e.g.\n\n`s3api.auth_details`\n\n... when it creates environ keys for communicating with other *swift components* it prefixes them with `swift` (same prefix as all other swift compoents use for intra-components communication via environ) e.g.\n\n`swift.backend_path`\n\n... interestingly there is *also* a `s3api.backend_path` which I *think* has something to do with s3api keeping track of subrequests (again internal to s3api).\n\nSo I guess the best environ key for proxy-logging to expose as it\u0027s interface would be:\n\n`swift.s3_access_key_id` or maybe something more generic like `swift.access_log_user_id`","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"f0159691dd6a26d734423b6053cc30bd71b43304","unresolved":false,"context_lines":[{"line_number":1052,"context_line":"        self._timestamp \u003d None"},{"line_number":1053,"context_line":"        self.access_key, self.signature \u003d self._parse_auth_info()"},{"line_number":1054,"context_line":"        # Store access key in environment for proxy logging"},{"line_number":1055,"context_line":"        self.environ[\u0027s3api.access_key\u0027] \u003d self.access_key"},{"line_number":1056,"context_line":"        self.bucket_in_host \u003d self._parse_host()"},{"line_number":1057,"context_line":"        self.container_name, self.object_name \u003d self._parse_uri()"},{"line_number":1058,"context_line":"        self._validate_headers()"}],"source_content_type":"text/x-python","patch_set":2,"id":"364de616_f37f2389","line":1055,"in_reply_to":"ede2815d_e05b08b4","updated":"2025-07-21 15:55:00.000000000","message":"Done","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"65e7d250863f7d3b72c22e4d34d0c325b0d4ae2e","unresolved":true,"context_lines":[{"line_number":1096,"context_line":"            \u0027signature\u0027: self.signature,"},{"line_number":1097,"context_line":"            \u0027string_to_sign\u0027: self.sig_checker.string_to_sign,"},{"line_number":1098,"context_line":"            \u0027check_signature\u0027: self.sig_checker.check_signature,"},{"line_number":1099,"context_line":"        }"},{"line_number":1100,"context_line":"        self.account \u003d None"},{"line_number":1101,"context_line":"        self.user_id \u003d None"},{"line_number":1102,"context_line":"        self.policy_index \u003d None"}],"source_content_type":"text/x-python","patch_set":2,"id":"07a921de_a323d3dc","line":1099,"updated":"2025-07-16 19:42:31.000000000","message":"I might move the adding of self.access_key to the environ down here... or move this up there?  Or move `_parse_auth_info` down here?  I don\u0027t know why it\u0027s all spread out, but consolidation would be a (minor?) improvement.  At least it\u0027s all in the same method!","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"f0159691dd6a26d734423b6053cc30bd71b43304","unresolved":false,"context_lines":[{"line_number":1096,"context_line":"            \u0027signature\u0027: self.signature,"},{"line_number":1097,"context_line":"            \u0027string_to_sign\u0027: self.sig_checker.string_to_sign,"},{"line_number":1098,"context_line":"            \u0027check_signature\u0027: self.sig_checker.check_signature,"},{"line_number":1099,"context_line":"        }"},{"line_number":1100,"context_line":"        self.account \u003d None"},{"line_number":1101,"context_line":"        self.user_id \u003d None"},{"line_number":1102,"context_line":"        self.policy_index \u003d None"}],"source_content_type":"text/x-python","patch_set":2,"id":"4fe41f9f_4d206ec3","line":1099,"in_reply_to":"07a921de_a323d3dc","updated":"2025-07-21 15:55:00.000000000","message":"Done2","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"48cb23e50e05e5e63584d7ee1638db397f624669","unresolved":true,"context_lines":[{"line_number":1101,"context_line":"        }"},{"line_number":1102,"context_line":"        # Set the logging field (if not set already)"},{"line_number":1103,"context_line":"        self.environ.setdefault(\u0027swift.proxy_logging_access_key\u0027,"},{"line_number":1104,"context_line":"                                self.access_key)"},{"line_number":1105,"context_line":"        self.account \u003d None"},{"line_number":1106,"context_line":"        self.user_id \u003d None"},{"line_number":1107,"context_line":"        self.policy_index \u003d None"}],"source_content_type":"text/x-python","patch_set":10,"id":"8544b70d_ddc5c8a5","line":1104,"updated":"2025-07-23 20:37:38.000000000","message":"ah, this is why access_key seemed like a reasonable name for the log field.\n\nhere s3api of course doesn\u0027t know the secret - that\u0027s why it passes the signature \u0026 string_to_sign and it\u0027s callback helper - so that auth mw can lookup the signing secret by access_key_id and verify the signature using the secret.\n\nunrelated: I wonder if this will have to add the session token if we port nvsts to use that for the claims bundle instead of the access_key.","commit_id":"88ed87f437d1a9c57c854ace5b251f02db64f953"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"a1a96c3122ba9ee4958f0114043361279ce5cd59","unresolved":false,"context_lines":[{"line_number":1101,"context_line":"        }"},{"line_number":1102,"context_line":"        # Set the logging field (if not set already)"},{"line_number":1103,"context_line":"        self.environ.setdefault(\u0027swift.proxy_logging_access_key\u0027,"},{"line_number":1104,"context_line":"                                self.access_key)"},{"line_number":1105,"context_line":"        self.account \u003d None"},{"line_number":1106,"context_line":"        self.user_id \u003d None"},{"line_number":1107,"context_line":"        self.policy_index \u003d None"}],"source_content_type":"text/x-python","patch_set":10,"id":"b3306198_414f847e","line":1104,"in_reply_to":"8544b70d_ddc5c8a5","updated":"2025-07-24 21:25:51.000000000","message":"Acknowledged","commit_id":"88ed87f437d1a9c57c854ace5b251f02db64f953"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"666064dd23044d190c1eca2bda0bd554e212b8b1","unresolved":true,"context_lines":[{"line_number":1101,"context_line":"        }"},{"line_number":1102,"context_line":"        # Set the logging field (if not set already)"},{"line_number":1103,"context_line":"        self.environ.setdefault(\u0027swift.access_logging\u0027, {}).setdefault("},{"line_number":1104,"context_line":"            \u0027user_id\u0027, self.access_key)"},{"line_number":1105,"context_line":"        self.account \u003d None"},{"line_number":1106,"context_line":"        self.user_id \u003d None"},{"line_number":1107,"context_line":"        self.policy_index \u003d None"}],"source_content_type":"text/x-python","patch_set":15,"id":"2058c365_33b4b7e0","line":1104,"updated":"2025-08-11 20:08:29.000000000","message":"the use of the mutable is somewhat subtle here, I wonder if it\u0027d be useful to leave a comment:\n\n```\nbecause auth mw to our right will only see a copy of the SwiftRequest environ we use a mutable value to back-propagate updates to proxy-logging\n```\n\n... might also be additional justification for \"better safe than sorry\" truncation:\n\n\n```\nvalue \u003d value[:125] + \u0027...\u0027 if len(value) \u003e 128 else value\n```","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":1101,"context_line":"        }"},{"line_number":1102,"context_line":"        # Set the logging field (if not set already)"},{"line_number":1103,"context_line":"        self.environ.setdefault(\u0027swift.access_logging\u0027, {}).setdefault("},{"line_number":1104,"context_line":"            \u0027user_id\u0027, self.access_key)"},{"line_number":1105,"context_line":"        self.account \u003d None"},{"line_number":1106,"context_line":"        self.user_id \u003d None"},{"line_number":1107,"context_line":"        self.policy_index \u003d None"}],"source_content_type":"text/x-python","patch_set":15,"id":"6d0ab0ec_dc3b784a","line":1104,"in_reply_to":"2058c365_33b4b7e0","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6061561d4c4ebe27bc17444426df3a3b25053e40","unresolved":true,"context_lines":[{"line_number":1101,"context_line":"        }"},{"line_number":1102,"context_line":"        # Set the logging field (if not set already)"},{"line_number":1103,"context_line":"        # Because auth mw to our right will only see a copy of the SwiftRequest"},{"line_number":1104,"context_line":"        # environ we use a mutable value to back-propagate updates to proxy-log"},{"line_number":1105,"context_line":"        access_key_value \u003d (self.access_key[:125] + \u0027...\u0027"},{"line_number":1106,"context_line":"                            if len(self.access_key) \u003e 128"},{"line_number":1107,"context_line":"                            else self.access_key)"}],"source_content_type":"text/x-python","patch_set":19,"id":"932b7242_64dbbf4f","line":1104,"updated":"2025-08-22 02:07:35.000000000","message":"this doc is a smell - it\u0027s suggesting that it\u0027s really important to make sure this mutable value already exists in the *original* request envion in-case anyone is doing a shallow copy, but we\u0027re using setdefault because until you get here... no one else has actually set it yet?\n\nI think proxy-logging should a) make sure the mutable key is set on the way in b) document (test) more WHY it does this and how it needs to work:\n\n958251: sq? tests and docs | https://review.opendev.org/c/openstack/swift/+/958251","commit_id":"0c68af898666c71fa96ea36b0c9ef886a791808e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6061561d4c4ebe27bc17444426df3a3b25053e40","unresolved":true,"context_lines":[{"line_number":1104,"context_line":"        # environ we use a mutable value to back-propagate updates to proxy-log"},{"line_number":1105,"context_line":"        access_key_value \u003d (self.access_key[:125] + \u0027...\u0027"},{"line_number":1106,"context_line":"                            if len(self.access_key) \u003e 128"},{"line_number":1107,"context_line":"                            else self.access_key)"},{"line_number":1108,"context_line":"        self.environ.setdefault(\u0027swift.access_logging\u0027, {}).setdefault("},{"line_number":1109,"context_line":"            \u0027user_id\u0027, access_key_value)"},{"line_number":1110,"context_line":"        self.account \u003d None"}],"source_content_type":"text/x-python","patch_set":19,"id":"d8557dc9_7c644542","line":1107,"updated":"2025-08-22 02:07:35.000000000","message":"the truncation here is nice (IMHO); but un-tested\n\n958251: sq? tests and docs | https://review.opendev.org/c/openstack/swift/+/958251","commit_id":"0c68af898666c71fa96ea36b0c9ef886a791808e"}],"swift/common/middleware/tempauth.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":295,"context_line":"        if self.allow_overrides and env.get(\u0027swift.authorize_override\u0027, False):"},{"line_number":296,"context_line":"            return self.app(env, start_response)"},{"line_number":297,"context_line":"        if env.get(\u0027PATH_INFO\u0027, \u0027\u0027).startswith(self.auth_prefix):"},{"line_number":298,"context_line":"            return self.handle(env, start_response)"},{"line_number":299,"context_line":"        s3 \u003d env.get(\u0027s3api.auth_details\u0027) or env.get(\u0027swift3.auth_details\u0027)"},{"line_number":300,"context_line":"        token \u003d env.get(\u0027HTTP_X_AUTH_TOKEN\u0027, env.get(\u0027HTTP_X_STORAGE_TOKEN\u0027))"},{"line_number":301,"context_line":"        service_token \u003d env.get(\u0027HTTP_X_SERVICE_TOKEN\u0027)"}],"source_content_type":"text/x-python","patch_set":15,"id":"eb12d494_dbf4e2e5","line":298,"updated":"2025-08-11 19:53:51.000000000","message":"FWIW I think it\u0027s perfectly reasonable that `/auth/v1.0` requests do NOT set `access_logging.user_id` - which I tend to think of as more of a dataplane access field.\n\n```\nAug 11 19:32:31 saio proxy-server: 127.0.0.1 127.0.0.1 11/Aug/2025/19/32/31 GET /auth/v1.0 HTTP/1.0 200 - python-swiftclient-4.7.0.dev3 - - - - tx10cdc93c87c54b75beef6-00689a454f - 0.0007 - - 1754940751.556274414 1754940751.556937218 - -\n```\n\n... but the definitely *could*\n\n```\ndiff --git a/swift/common/middleware/tempauth.py b/swift/common/middleware/tempauth.py\nindex 851b70df4..4daaac4f4 100644\n--- a/swift/common/middleware/tempauth.py\n+++ b/swift/common/middleware/tempauth.py\n@@ -881,6 +881,8 @@ class TempAuth(object):\n         user \u003d wsgi_to_str(user)\n         key \u003d wsgi_to_str(key)\n         account_user \u003d account + \u0027:\u0027 + user\n+        req.environ.setdefault(\n+            \u0027swift.access_logging\u0027, {})[\u0027user_id\u0027] \u003d account_user\n         if account_user not in self.users:\n             self.logger.increment(\u0027token_denied\u0027)\n             return HTTPUnauthorized(request\u003dreq, headers\u003dunauthed_headers)\n```\n\nit would just mean more testing; so I think I\u0027m ok with YAGNI - esp for tempauth.","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":295,"context_line":"        if self.allow_overrides and env.get(\u0027swift.authorize_override\u0027, False):"},{"line_number":296,"context_line":"            return self.app(env, start_response)"},{"line_number":297,"context_line":"        if env.get(\u0027PATH_INFO\u0027, \u0027\u0027).startswith(self.auth_prefix):"},{"line_number":298,"context_line":"            return self.handle(env, start_response)"},{"line_number":299,"context_line":"        s3 \u003d env.get(\u0027s3api.auth_details\u0027) or env.get(\u0027swift3.auth_details\u0027)"},{"line_number":300,"context_line":"        token \u003d env.get(\u0027HTTP_X_AUTH_TOKEN\u0027, env.get(\u0027HTTP_X_STORAGE_TOKEN\u0027))"},{"line_number":301,"context_line":"        service_token \u003d env.get(\u0027HTTP_X_SERVICE_TOKEN\u0027)"}],"source_content_type":"text/x-python","patch_set":15,"id":"2293fe4f_0179aedb","line":298,"in_reply_to":"eb12d494_dbf4e2e5","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":319,"context_line":"                env[\u0027swift.authorize\u0027] \u003d self.authorize"},{"line_number":320,"context_line":"                env[\u0027swift.clean_acl\u0027] \u003d clean_acl"},{"line_number":321,"context_line":"                # Set access_user_id for consistent logging across middlewares"},{"line_number":322,"context_line":"                env.setdefault(\u0027swift.access_logging\u0027, {})[\u0027user_id\u0027] \u003d user"},{"line_number":323,"context_line":"                if \u0027.reseller_admin\u0027 in groups:"},{"line_number":324,"context_line":"                    env[\u0027reseller_request\u0027] \u003d True"},{"line_number":325,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"7e7291fd_d7625cf4","line":322,"updated":"2025-08-11 19:53:51.000000000","message":"this should have a corresponding test change\n\n```\nAug 11 19:32:31 saio proxy-server: 127.0.0.1 127.0.0.1 11/Aug/2025/19/32/31 HEAD /v1/AUTH_test%3Fformat%3Djson HTTP/1.0 204 - python-swiftclient-4.7.0.dev3 AUTH_tk11908a510... - - - txe9c4ee2ca5f94bee87e21-00689a454f - 0.0086 - - 1754940751.559271336 1754940751.567853928 - test:tester\n```\n\n^ we\u0027re changing the default tempauth behavior.\n\nThere\u0027s lots of reasonable places we could assert this value is set:\n\n```\ndiff --git a/test/unit/common/middleware/test_tempauth.py b/test/unit/common/middleware/test_tempauth.py\nindex 7fcb4acab..6acc69ae5 100644\n--- a/test/unit/common/middleware/test_tempauth.py\n+++ b/test/unit/common/middleware/test_tempauth.py\n@@ -1135,7 +1135,10 @@ class TestAuth(unittest.TestCase):\n         req \u003d self._make_request(\n             quoted_acct, headers\u003d{\u0027X-Auth-Token\u0027: auth_token})\n         req.environ[\u0027swift.cache\u0027] \u003d memcache\n+        self.assertNotIn(\u0027swift.access_logging\u0027, req.environ)\n         resp \u003d req.get_response(ath)\n+        self.assertEqual(req.environ[\u0027swift.access_logging\u0027],\n+                         {\u0027user_id\u0027: \u0027t\\u00e9st:t\\u00e9setr\u0027})\n         self.assertEqual(204, resp.status_int)\n \n         # ...but it also works if you send the account raw\n```","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":319,"context_line":"                env[\u0027swift.authorize\u0027] \u003d self.authorize"},{"line_number":320,"context_line":"                env[\u0027swift.clean_acl\u0027] \u003d clean_acl"},{"line_number":321,"context_line":"                # Set access_user_id for consistent logging across middlewares"},{"line_number":322,"context_line":"                env.setdefault(\u0027swift.access_logging\u0027, {})[\u0027user_id\u0027] \u003d user"},{"line_number":323,"context_line":"                if \u0027.reseller_admin\u0027 in groups:"},{"line_number":324,"context_line":"                    env[\u0027reseller_request\u0027] \u003d True"},{"line_number":325,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"205bdd5f_c084cf5b","line":322,"in_reply_to":"7e7291fd_d7625cf4","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6061561d4c4ebe27bc17444426df3a3b25053e40","unresolved":true,"context_lines":[{"line_number":836,"context_line":"        except ValueError:"},{"line_number":837,"context_line":"            self.logger.increment(\u0027errors\u0027)"},{"line_number":838,"context_line":"            return HTTPNotFound(request\u003dreq)"},{"line_number":839,"context_line":"        if pathsegs[0] \u003d\u003d \u0027v1\u0027 and pathsegs[2] \u003d\u003d \u0027auth\u0027:"},{"line_number":840,"context_line":"            account \u003d pathsegs[1]"},{"line_number":841,"context_line":"            user \u003d req.headers.get(\u0027x-storage-user\u0027)"},{"line_number":842,"context_line":"            if not user:"}],"source_content_type":"text/x-python","patch_set":18,"id":"4d350862_530a45f0","line":839,"updated":"2025-08-22 02:07:35.000000000","message":"unrelated: \n\nI have no idea what this whole block is even for:\n\n958122: tempauth: remove un-tested mis-feature | https://review.opendev.org/c/openstack/swift/+/958122","commit_id":"2e2f8a94c65b400eac38637dd31b9a678919fefb"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6061561d4c4ebe27bc17444426df3a3b25053e40","unresolved":true,"context_lines":[{"line_number":885,"context_line":"            \u0027swift.access_logging\u0027, {})[\u0027user_id\u0027] \u003d account_user"},{"line_number":886,"context_line":"        if account_user not in self.users:"},{"line_number":887,"context_line":"            self.logger.increment(\u0027token_denied\u0027)"},{"line_number":888,"context_line":"            return HTTPUnauthorized(request\u003dreq, headers\u003dunauthed_headers)"},{"line_number":889,"context_line":"        if self.users[account_user][\u0027key\u0027] !\u003d key:"},{"line_number":890,"context_line":"            self.logger.increment(\u0027token_denied\u0027)"},{"line_number":891,"context_line":"            return HTTPUnauthorized(request\u003dreq, headers\u003dunauthed_headers)"}],"source_content_type":"text/x-python","patch_set":18,"id":"aff18936_57301d79","line":888,"updated":"2025-08-22 02:07:35.000000000","message":"is it weird that *some* 401 will have the user_id and some won\u0027t?\n\n```\ndiff --git a/test/unit/common/middleware/test_tempauth.py b/test/unit/common/middleware/test_tempauth.py\nindex 7d39ee877..224ed48f2 100644\n--- a/test/unit/common/middleware/test_tempauth.py\n+++ b/test/unit/common/middleware/test_tempauth.py\n@@ -645,6 +645,41 @@ class TestAuth(unittest.TestCase):\n                                auth.DEFAULT_TOKEN_LIFE - 0.5, delta\u003d0.5)\n         self.assertGreater(len(resp.headers[\u0027x-auth-token\u0027]), 10)\n \n+    def test_get_token_unauthorized(self):\n+        test_auth \u003d auth.filter_factory({\u0027user_ac_user\u0027: \u0027testing\u0027})(FakeApp())\n+        # if we get a syntactically valid, but incorrect auth request, we\n+        # should set access_logging.user_id\n+        req \u003d self._make_request(\n+            \u0027/auth/v1.0\u0027,\n+            headers\u003d{\u0027X-Auth-User\u0027: \u0027ac:user\u0027, \u0027X-Auth-Key\u0027: \u0027testing-typo\u0027})\n+        resp \u003d req.get_response(test_auth)\n+        self.assertEqual(resp.status_int, 401)\n+        self.assertEqual(req.environ[\u0027swift.access_logging\u0027][\u0027user_id\u0027],\n+                         \u0027ac:user\u0027)\n+\n+        req \u003d self._make_request(\n+            \u0027/auth/v1.0\u0027,\n+            headers\u003d{\u0027X-Auth-User\u0027: \u0027ac:user-does-not-exist\u0027, \u0027X-Auth-Key\u0027: \u0027testing\u0027})\n+        resp \u003d req.get_response(test_auth)\n+        self.assertEqual(resp.status_int, 401)\n+        self.assertEqual(req.environ[\u0027swift.access_logging\u0027][\u0027user_id\u0027],\n+                         \u0027ac:user-does-not-exist\u0027)\n+\n+        # otherwise, not\n+        req \u003d self._make_request(\n+            \u0027/auth/v1.0\u0027,\n+            headers\u003d{\u0027X-Auth-User\u0027: \u0027ac:user\u0027})\n+        resp \u003d req.get_response(test_auth)\n+        self.assertEqual(resp.status_int, 401)\n+        self.assertNotIn(\u0027swift.access_logging\u0027, req.environ)\n+\n+        req \u003d self._make_request(\n+            \u0027/auth/v1.0\u0027,\n+            headers\u003d{\u0027X-Auth-Key\u0027: \u0027testing\u0027})\n+        resp \u003d req.get_response(test_auth)\n+        self.assertEqual(resp.status_int, 401)\n+        self.assertNotIn(\u0027swift.access_logging\u0027, req.environ)\n+\n     def test_get_token_sets_access_logging_user_id(self):\n         # Test that token generation sets access logging user_id\n         test_auth \u003d auth.filter_factory({\u0027user_ac_user\u0027: \u0027testing\u0027})(FakeApp())````","commit_id":"2e2f8a94c65b400eac38637dd31b9a678919fefb"}],"test/unit/common/middleware/s3api/test_obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"48cb23e50e05e5e63584d7ee1638db397f624669","unresolved":true,"context_lines":[{"line_number":205,"context_line":"        self.assertEqual(\u0027 \u0027.join(parts[3:7]),"},{"line_number":206,"context_line":"                         \u0027GET /bucket/object HTTP/1.0 200\u0027)"},{"line_number":207,"context_line":"        self.assertEqual(parts[-2], str(bucket_policy_index))"},{"line_number":208,"context_line":"        self.assertEqual(parts[-1], \u0027test:tester\u0027)  # proxy_logging_access_key"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    def _test_object_HEAD_Range(self, range_value):"},{"line_number":211,"context_line":"        req \u003d Request.blank(\u0027/bucket/object\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"bc73783c_ca737269","line":208,"updated":"2025-07-23 20:37:38.000000000","message":"if there are anymore tests that use this `ProxyLoggingMiddleware(self.s3api` pattern I think it\u0027d be nice to add as much coverage as possible on \"s3api will set the `access_logging_user_id` field to match the `s3_access_key_id`\"\n\n... esp for alternative authorization signature formats.  I assume there\u0027s ome v4 tests in here *somewhere*\n\nIn fact it may be reasonable to add `ProxyLoggingMiddleware` wrapping to some existing V4 tests if they don\u0027t exist since we expect a lot of s3api sdk\u0027s and clients will use that signing format by default.","commit_id":"88ed87f437d1a9c57c854ace5b251f02db64f953"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"06a55121ff2ad620a062ec3b4934288f32d367d1","unresolved":false,"context_lines":[{"line_number":205,"context_line":"        self.assertEqual(\u0027 \u0027.join(parts[3:7]),"},{"line_number":206,"context_line":"                         \u0027GET /bucket/object HTTP/1.0 200\u0027)"},{"line_number":207,"context_line":"        self.assertEqual(parts[-2], str(bucket_policy_index))"},{"line_number":208,"context_line":"        self.assertEqual(parts[-1], \u0027test:tester\u0027)  # proxy_logging_access_key"},{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    def _test_object_HEAD_Range(self, range_value):"},{"line_number":211,"context_line":"        req \u003d Request.blank(\u0027/bucket/object\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"cafb2ec5_a67e0663","line":208,"in_reply_to":"bc73783c_ca737269","updated":"2025-07-28 15:09:32.000000000","message":"Agree, added some v4 tests. For places where the entire ProxyLoggingMiddleware is not there, I am just checking that the value is set in environ","commit_id":"88ed87f437d1a9c57c854ace5b251f02db64f953"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":84,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: method},"},{"line_number":85,"context_line":"                            headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,"},{"line_number":86,"context_line":"                                     \u0027Date\u0027: self.get_date_header()})"},{"line_number":87,"context_line":"        status, headers, body \u003d self.call_s3api(req)"},{"line_number":88,"context_line":"        self.assertEqual(status.split()[0], \u0027200\u0027)"},{"line_number":89,"context_line":"        # we\u0027ll want this for logging"},{"line_number":90,"context_line":"        self._assert_policy_index(req.headers, headers,"}],"source_content_type":"text/x-python","patch_set":15,"id":"c5d5888f_94347783","line":87,"updated":"2025-08-11 19:53:51.000000000","message":"I think we\u0027d get pretty good bang for our buck on read requests w/ v2 signatures here:\n\n```\ndiff --git a/test/unit/common/middleware/s3api/test_obj.py b/test/unit/common/middleware/s3api/test_obj.py\nindex ce4fedc00..7e14b921c 100644\n--- a/test/unit/common/middleware/s3api/test_obj.py\n+++ b/test/unit/common/middleware/s3api/test_obj.py\n@@ -84,7 +84,10 @@ class BaseS3ApiObj(object):\n                             environ\u003d{\u0027REQUEST_METHOD\u0027: method},\n                             headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,\n                                      \u0027Date\u0027: self.get_date_header()})\n+        self.assertNotIn(\u0027swift.access_logging\u0027, req.environ)\n         status, headers, body \u003d self.call_s3api(req)\n+        self.assertEqual(req.environ[\u0027swift.access_logging\u0027],\n+                         {\u0027user_id\u0027: \u0027test:tetser\u0027})\n         self.assertEqual(status.split()[0], \u0027200\u0027)\n         # we\u0027ll want this for logging\n         self._assert_policy_index(req.headers, headers,\n```\n\n```\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObj::test_object_GET - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObj::test_object_HEAD - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjNonUTC::test_object_GET - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjNonUTC::test_object_HEAD - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjAcl::test_object_GET - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjAcl::test_object_GET_with_s3acl_and_keystone - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjAcl::test_object_HEAD - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjNonUTCAcl::test_object_GET - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjNonUTCAcl::test_object_GET_with_s3acl_and_keystone - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjNonUTCAcl::test_object_HEAD - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\n```","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":84,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: method},"},{"line_number":85,"context_line":"                            headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,"},{"line_number":86,"context_line":"                                     \u0027Date\u0027: self.get_date_header()})"},{"line_number":87,"context_line":"        status, headers, body \u003d self.call_s3api(req)"},{"line_number":88,"context_line":"        self.assertEqual(status.split()[0], \u0027200\u0027)"},{"line_number":89,"context_line":"        # we\u0027ll want this for logging"},{"line_number":90,"context_line":"        self._assert_policy_index(req.headers, headers,"}],"source_content_type":"text/x-python","patch_set":15,"id":"3d597e3d_8010c96c","line":87,"in_reply_to":"c5d5888f_94347783","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":833,"context_line":"            body\u003dself.object_body)"},{"line_number":834,"context_line":"        req.date \u003d datetime.now()"},{"line_number":835,"context_line":"        req.content_type \u003d \u0027text/plain\u0027"},{"line_number":836,"context_line":"        status, headers, body \u003d self.call_s3api(req)"},{"line_number":837,"context_line":"        self.assertEqual(status.split()[0], \u0027400\u0027)"},{"line_number":838,"context_line":"        self.assertEqual(self._get_error_code(body),"},{"line_number":839,"context_line":"                         \u0027XAmzContentSHA256Mismatch\u0027)"}],"source_content_type":"text/x-python","patch_set":15,"id":"a6a8d562_8f1b4615","line":836,"updated":"2025-08-11 19:53:51.000000000","message":"as best I can tell any of these tests could have made assertions on this behavior:\n\n```\ndiff --git a/test/unit/common/middleware/s3api/test_obj.py b/test/unit/common/middleware/s3api/test_obj.py\nindex ce4fedc00..a64e83a6e 100644\n--- a/test/unit/common/middleware/s3api/test_obj.py\n+++ b/test/unit/common/middleware/s3api/test_obj.py\n@@ -833,7 +833,10 @@ class BaseS3ApiObj(object):\n             body\u003dself.object_body)\n         req.date \u003d datetime.now()\n         req.content_type \u003d \u0027text/plain\u0027\n+        self.assertNotIn(\u0027swift.access_logging\u0027, req.environ)\n         status, headers, body \u003d self.call_s3api(req)\n+        self.assertEqual(req.environ[\u0027swift.access_logging\u0027],\n+                         {\u0027user_id\u0027: \u0027test:tetser\u0027})\n         self.assertEqual(status.split()[0], \u0027400\u0027)\n         self.assertEqual(self._get_error_code(body),\n                          \u0027XAmzContentSHA256Mismatch\u0027)\n```\n\nI think we\u0027re getting pretty good coverage just cherry-picking some at random:\n\n```\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObj::test_object_PUT_v4_bad_hash - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjNonUTC::test_object_PUT_v4_bad_hash - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjAcl::test_object_PUT_v4_bad_hash - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\nFAILED swift/test/unit/common/middleware/s3api/test_obj.py::TestS3ApiObjNonUTCAcl::test_object_PUT_v4_bad_hash - AssertionError: {\u0027user_id\u0027: \u0027test:tester\u0027} !\u003d {\u0027user_id\u0027: \u0027test:tetser\u0027}\n```","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":833,"context_line":"            body\u003dself.object_body)"},{"line_number":834,"context_line":"        req.date \u003d datetime.now()"},{"line_number":835,"context_line":"        req.content_type \u003d \u0027text/plain\u0027"},{"line_number":836,"context_line":"        status, headers, body \u003d self.call_s3api(req)"},{"line_number":837,"context_line":"        self.assertEqual(status.split()[0], \u0027400\u0027)"},{"line_number":838,"context_line":"        self.assertEqual(self._get_error_code(body),"},{"line_number":839,"context_line":"                         \u0027XAmzContentSHA256Mismatch\u0027)"}],"source_content_type":"text/x-python","patch_set":15,"id":"b92b0cdf_94d1bcf1","line":836,"in_reply_to":"a6a8d562_8f1b4615","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"}],"test/unit/common/middleware/s3api/test_s3api.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":28,"context_line":"from urllib.parse import unquote, quote"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"import swift.common.middleware.s3api"},{"line_number":31,"context_line":"from swift.common.middleware.proxy_logging import ProxyLoggingMiddleware"},{"line_number":32,"context_line":"from swift.common.middleware.s3api.s3response import ErrorResponse, \\"},{"line_number":33,"context_line":"    AccessDenied"},{"line_number":34,"context_line":"from swift.common.middleware.s3api.utils import Config"}],"source_content_type":"text/x-python","patch_set":15,"id":"3b9d8e4e_12b41ebc","line":31,"updated":"2025-08-11 19:53:51.000000000","message":"it looks like this came in for `test_error_response_reason_logging` - I think it\u0027s reasonable to adopt it to other tests.","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":28,"context_line":"from urllib.parse import unquote, quote"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"import swift.common.middleware.s3api"},{"line_number":31,"context_line":"from swift.common.middleware.proxy_logging import ProxyLoggingMiddleware"},{"line_number":32,"context_line":"from swift.common.middleware.s3api.s3response import ErrorResponse, \\"},{"line_number":33,"context_line":"    AccessDenied"},{"line_number":34,"context_line":"from swift.common.middleware.s3api.utils import Config"}],"source_content_type":"text/x-python","patch_set":15,"id":"a855b240_f5bdad15","line":31,"in_reply_to":"3b9d8e4e_12b41ebc","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":1777,"context_line":"        req.content_type \u003d \u0027text/plain\u0027"},{"line_number":1778,"context_line":"        log_conf \u003d {\u0027log_msg_template\u0027: \u0027{method} {path} {log_info}\u0027}"},{"line_number":1779,"context_line":"        app \u003d ProxyLoggingMiddleware(self.s3api, log_conf, self.logger)"},{"line_number":1780,"context_line":"        status, headers, body \u003d self.call_app(req, app\u003dapp)"},{"line_number":1781,"context_line":""},{"line_number":1782,"context_line":"        self.assertEqual("},{"line_number":1783,"context_line":"            [\u0027403.AccessDenied.invalid_credential\u0027],"}],"source_content_type":"text/x-python","patch_set":15,"id":"15683d10_e68a96f6","line":1780,"updated":"2025-08-11 19:53:51.000000000","message":"FWIW when s3api fails to authorize a request it does NOT seem to set the env key:\n\n```\ndiff --git a/test/unit/common/middleware/s3api/test_s3api.py b/test/unit/common/middleware/s3api/test_s3api.py\nindex 5b309ef21..c6eeaba5f 100644\n--- a/test/unit/common/middleware/s3api/test_s3api.py\n+++ b/test/unit/common/middleware/s3api/test_s3api.py\n@@ -1777,7 +1777,9 @@ class TestS3ApiMiddleware(S3ApiTestCase):\n         req.content_type \u003d \u0027text/plain\u0027\n         log_conf \u003d {\u0027log_msg_template\u0027: \u0027{method} {path} {log_info}\u0027}\n         app \u003d ProxyLoggingMiddleware(self.s3api, log_conf, self.logger)\n+        self.assertNotIn(\u0027swift.access_logging\u0027, req.environ)\n         status, headers, body \u003d self.call_app(req, app\u003dapp)\n+        self.assertNotIn(\u0027swift.access_logging\u0027, req.environ)\n \n         self.assertEqual(\n             [\u0027403.AccessDenied.invalid_credential\u0027],\n```\n\n... I think that\u0027s ok, but also not necessarily something we\u0027d like to call out as an expected behavior.  I think it\u0027s correct for proxy-logging to assume it should use `environ.get(\u0027swift.access_logging\u0027, {}).get(\u0027user_id\u0027)`","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":1777,"context_line":"        req.content_type \u003d \u0027text/plain\u0027"},{"line_number":1778,"context_line":"        log_conf \u003d {\u0027log_msg_template\u0027: \u0027{method} {path} {log_info}\u0027}"},{"line_number":1779,"context_line":"        app \u003d ProxyLoggingMiddleware(self.s3api, log_conf, self.logger)"},{"line_number":1780,"context_line":"        status, headers, body \u003d self.call_app(req, app\u003dapp)"},{"line_number":1781,"context_line":""},{"line_number":1782,"context_line":"        self.assertEqual("},{"line_number":1783,"context_line":"            [\u0027403.AccessDenied.invalid_credential\u0027],"}],"source_content_type":"text/x-python","patch_set":15,"id":"f99f6bed_1eb8bccc","line":1780,"in_reply_to":"15683d10_e68a96f6","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6061561d4c4ebe27bc17444426df3a3b25053e40","unresolved":true,"context_lines":[{"line_number":1779,"context_line":"        app \u003d ProxyLoggingMiddleware(self.s3api, log_conf, self.logger)"},{"line_number":1780,"context_line":"        self.assertNotIn(\u0027swift.access_logging\u0027, req.environ)"},{"line_number":1781,"context_line":"        status, headers, body \u003d self.call_app(req, app\u003dapp)"},{"line_number":1782,"context_line":"        self.assertNotIn(\u0027swift.access_logging\u0027, req.environ)"},{"line_number":1783,"context_line":""},{"line_number":1784,"context_line":"        self.assertEqual("},{"line_number":1785,"context_line":"            [\u0027403.AccessDenied.invalid_credential\u0027],"}],"source_content_type":"text/x-python","patch_set":19,"id":"acb45324_2c2b81df","line":1782,"updated":"2025-08-22 02:07:35.000000000","message":"So, it\u0027s kind of confusing when we do and don\u0027t set swift.access_logging - this is highlighting that it\u0027s possible to return a valid s3api *error* w/o ever creating an S3Request object because there\u0027s a bunch of validation in `S3Request.__init__` that will raise s3 errors when trying to parse auth headers.\n\nBut that doesn\u0027t mean \"every 403/401 will not have access_logging.user_id\" - if the request is delay_denied (which is common for most operations, e.g. read/write object, i.e. we have to let the request get into the proxy to find out if it\u0027s allowed by ACLs) then we DO fully create the S3Request object and will have set access_logging even in the 403 response!\n\n... except maybe there\u0027s some other pre-flight request validation (i.e. 400) that can have valid auth but still error w/o setting the user_id?\n\n```\n        self.swift.register(method, uri, response_class, headers, None)\n        headers.update({\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,\n                        \u0027Date\u0027: self.get_date_header()})\n        env.update({\u0027REQUEST_METHOD\u0027: method})\n        req \u003d swob.Request.blank(path, environ\u003denv, headers\u003dheaders)\n        status, headers, body \u003d self.call_s3api(req)\n        # when the an error is returned from the proxy s3api has already\n        # created the S3Request and will always have set the\n        # access_logging.user_id\n\u003e       self.assertEqual(req.environ[\u0027swift.access_logging\u0027][\u0027user_id\u0027],\n                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n                         \u0027test:tester\u0027)\nE       KeyError: \u0027swift.access_logging\u0027\n\nswift/test/unit/common/middleware/s3api/__init__.py:197: KeyError\n\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e entering PDB \u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\n\n\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e PDB post_mortem \u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\u003e\n\u003e /home/vagrant/swift/test/unit/common/middleware/s3api/__init__.py(197)_test_method_error()\n-\u003e self.assertEqual(req.environ[\u0027swift.access_logging\u0027][\u0027user_id\u0027],\n(Pdb) !body\nb\"\u003c?xml version\u003d\u00271.0\u0027 encoding\u003d\u0027UTF-8\u0027?\u003e\\n\u003cError\u003e\u003cCode\u003eInvalidArgument\u003c/Code\u003e\u003cMessage\u003eCopy Source must mention the source bucket and key: sourcebucket/sourcekey\u003c/Message\u003e\u003cArgumentName\u003ex-amz-copy-source\u003c/ArgumentName\u003e\u003cArgumentValue\u003e\u003c/ArgumentValue\u003e\u003c/Error\u003e\"\n```\n\n... after debugging I had to re-jigger the order of validate helpers in `__init__`:\n\n958251: sq? tests and docs | https://review.opendev.org/c/openstack/swift/+/958251","commit_id":"0c68af898666c71fa96ea36b0c9ef886a791808e"}],"test/unit/common/middleware/test_proxy_logging.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"65e7d250863f7d3b72c22e4d34d0c325b0d4ae2e","unresolved":true,"context_lines":[{"line_number":2183,"context_line":"        b\u0027\u0027.join(resp)"},{"line_number":2184,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":2185,"context_line":"        idx \u003d self.get_s3_access_key_log_index(app)"},{"line_number":2186,"context_line":"        self.assertEqual(log_parts[idx], \u0027AKIA_V4KEYID123456\u0027)"},{"line_number":2187,"context_line":""},{"line_number":2188,"context_line":"    def test_s3_access_key_id_from_env(self):"},{"line_number":2189,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})"}],"source_content_type":"text/x-python","patch_set":2,"id":"8adaed85_42be5857","line":2186,"updated":"2025-07-16 19:42:31.000000000","message":"yeah I think it\u0027d be better to have a test in test_s3api that validates when a request with these headers hits S3Request\u0027s _parse_auth_info that environ gets a `s3api.access_key` key so that the surface area of the proxy-logging code is smaller.\n\nI would expect that s3api testing hopefully already accounts for the multitudes of vageries of different supported aws signature headers - and if that abstraction is doing it\u0027s job and is maintainable - they could all return an access_key and are passed to auth-mw via s3api.auth_details and could also be shared with proxy-logging via `swift.access_log_user_id` or `s3api.access_key` or even pulled directly from the pre-existing `\u0027s3api.auth_details\u0027.get(\u0027access_key\u0027)` since that\u0027s already a supported interface that s3api can not easily change w/o requiring updates to a bunch of out-of-tree mw.","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"f0159691dd6a26d734423b6053cc30bd71b43304","unresolved":false,"context_lines":[{"line_number":2183,"context_line":"        b\u0027\u0027.join(resp)"},{"line_number":2184,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":2185,"context_line":"        idx \u003d self.get_s3_access_key_log_index(app)"},{"line_number":2186,"context_line":"        self.assertEqual(log_parts[idx], \u0027AKIA_V4KEYID123456\u0027)"},{"line_number":2187,"context_line":""},{"line_number":2188,"context_line":"    def test_s3_access_key_id_from_env(self):"},{"line_number":2189,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})"}],"source_content_type":"text/x-python","patch_set":2,"id":"d4b84bec_5578fd5c","line":2186,"in_reply_to":"8adaed85_42be5857","updated":"2025-07-21 15:55:00.000000000","message":"Acknowledged","commit_id":"6fd8a9966db4c78f47f8d798116e00daa2ab991f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"60271b5a8ba5b86f22fb0814e0a66390a52a9992","unresolved":true,"context_lines":[{"line_number":2161,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":2162,"context_line":"        b\u0027\u0027.join(resp)"},{"line_number":2163,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":2164,"context_line":"        self.assertEqual(log_parts[-1], \u0027test:tester\u0027)  # Last field"}],"source_content_type":"text/x-python","patch_set":15,"id":"a3e6ae91_b02bc8f4","line":2164,"updated":"2025-08-11 19:53:51.000000000","message":"in the interests of maintainability probably better to assert that this is field index 21 rather than \"the last one\" (which was previously policy-index and in the future might be ... `s3_err_reason`)\n\nIt might be nice to assert the negative condition here as well, although it\u0027s probably duplicated by `test_ensure_fields`\n\nIt would also be nice to setup an anonomyized crank turn as well if that\u0027s an important behavior to maintain.\n\n```\ndiff --git a/test/unit/common/middleware/test_proxy_logging.py b/test/unit/common/middleware/test_proxy_logging.py\nindex 15b148e45..d6fa90ce5 100644\n--- a/test/unit/common/middleware/test_proxy_logging.py\n+++ b/test/unit/common/middleware/test_proxy_logging.py\n@@ -2161,4 +2161,31 @@ class TestProxyLogging(unittest.TestCase):\n         resp \u003d app(req.environ, start_response)\n         b\u0027\u0027.join(resp)\n         log_parts \u003d self._log_parts(app)\n-        self.assertEqual(log_parts[-1], \u0027test:tester\u0027)  # Last field\n+        self.assertEqual(log_parts[21], \u0027test:tester\u0027)\n+\n+        # test that user_id is not logged if it is not present\n+        app \u003d proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})\n+        app.access_logger \u003d debug_logger()\n+        req \u003d Request.blank(\u0027/\u0027, environ\u003d{\n+            \u0027REQUEST_METHOD\u0027: \u0027GET\u0027,\n+        })\n+        resp \u003d app(req.environ, start_response)\n+        b\u0027\u0027.join(resp)\n+        log_parts \u003d self._log_parts(app)\n+        self.assertEqual(log_parts[21], \u0027-\u0027)\n+\n+    def test_access_user_id_field_with_anonymization(self):\n+        app \u003d proxy_logging.ProxyLoggingMiddleware(FakeApp(), {\n+            \u0027log_anonymization_salt\u0027: \u0027secret_salt\u0027,\n+            \u0027log_msg_template\u0027: \u0027{method} {path} {access_user_id.anonymized}\u0027\n+        })\n+        app.access_logger \u003d debug_logger()\n+        req \u003d Request.blank(\u0027/\u0027, environ\u003d{\n+            \u0027REQUEST_METHOD\u0027: \u0027GET\u0027,\n+            \u0027swift.access_logging\u0027: {\u0027user_id\u0027: \u0027test:tester\u0027},\n+        })\n+        resp \u003d app(req.environ, start_response)\n+        b\u0027\u0027.join(resp)\n+        log_parts \u003d self._log_parts(app)\n+        self.assertEqual(log_parts[-1],\n+                         \u0027{SMD5}14fe1612c332096e282486e4baa37e63\u0027)\n```","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"},{"author":{"_account_id":38213,"name":"Vitaly Bordyug","display_name":"Vitaly","email":"vbordug@gmail.com","username":"vitb"},"change_message_id":"73fbfdbb8bd51a3ce267234c425cd9ea110933fb","unresolved":false,"context_lines":[{"line_number":2161,"context_line":"        resp \u003d app(req.environ, start_response)"},{"line_number":2162,"context_line":"        b\u0027\u0027.join(resp)"},{"line_number":2163,"context_line":"        log_parts \u003d self._log_parts(app)"},{"line_number":2164,"context_line":"        self.assertEqual(log_parts[-1], \u0027test:tester\u0027)  # Last field"}],"source_content_type":"text/x-python","patch_set":15,"id":"2551e84c_8c041998","line":2164,"in_reply_to":"a3e6ae91_b02bc8f4","updated":"2025-08-18 19:22:44.000000000","message":"Done","commit_id":"fe1c89f96e0e9bc546f6001d013607aa14acbc58"}],"test/unit/common/middleware/test_tempauth.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6061561d4c4ebe27bc17444426df3a3b25053e40","unresolved":true,"context_lines":[{"line_number":657,"context_line":"        self.assertIn(\u0027swift.access_logging\u0027, req.environ)"},{"line_number":658,"context_line":"        self.assertIn(\u0027user_id\u0027, req.environ[\u0027swift.access_logging\u0027])"},{"line_number":659,"context_line":"        self.assertEqual(req.environ[\u0027swift.access_logging\u0027][\u0027user_id\u0027],"},{"line_number":660,"context_line":"                         \u0027ac:user\u0027)"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"    def test_get_token_memcache_error(self):"},{"line_number":663,"context_line":"        test_auth \u003d auth.filter_factory({\u0027user_ac_user\u0027: \u0027testing\u0027})(FakeApp())"}],"source_content_type":"text/x-python","patch_set":18,"id":"92ca56db_cdd5071c","line":660,"updated":"2025-08-22 02:07:35.000000000","message":"I think I\u0027m surprised to see this var getting added to the environ for the /auth request - It was obviously intentional tho - at least for swift-v1-auth... s3 style requests don\u0027t have a explicit authorization step; they just sign the request using their secret_key.","commit_id":"2e2f8a94c65b400eac38637dd31b9a678919fefb"}]}
