Skip to content

fix(server): log a fingerprint of rejected API keys instead of the raw key#1751

Merged
jundot merged 1 commit into
jundot:mainfrom
richgoodson:fix/1440-redact-rejected-key-log
Jun 10, 2026
Merged

fix(server): log a fingerprint of rejected API keys instead of the raw key#1751
jundot merged 1 commit into
jundot:mainfrom
richgoodson:fix/1440-redact-rejected-key-log

Conversation

@richgoodson

Copy link
Copy Markdown
Contributor

Addresses item 4 of #1440 (the rejected-key logging item).

Problem

When a request fails API key auth, server.py logs the rejected key verbatim at WARNING:

logger.warning("Rejected API key: %r", api_key_value)

That writes the client's secret into server.log on every failed auth, at an always-on level. A user who mistypes a key, or whose key carries the non-ASCII problem fixed in #1719, leaks their credential straight into the logs.

Fix

Log a short, non-reversible fingerprint instead of the raw value: the first 8 hex characters of the SHA-256 of the key. Operators can still correlate repeated rejections of the same key (a misconfigured client hammering the endpoint shows one stable fp=) without the secret ever landing in the log.

Added fingerprint_key to omlx/admin/auth.py, next to compare_keys, using the same encode("utf-8", "surrogatepass"). That keeps it tolerant of any str the auth path accepts, including the non-ASCII and lone-surrogate keys that #1719 already handles.

Testing

  • 6 new tests in tests/test_api_auth.py: fingerprint format (8 hex chars), determinism, that the fingerprint does not contain the raw secret, that distinct keys differ, that non-ASCII / empty / lone-surrogate inputs do not raise, and an end-to-end check that the auth dependency logs the fingerprint and not the raw rejected key (via caplog).
  • Full suite: 5347 passed, 22 skipped, 66 deselected, 0 failed.
  • Live test: started a server with OMLX_API_KEY set, sent a wrong Bearer key to /v1/models, and confirmed the server log shows Rejected API key (fp=...), does not contain the raw key, and that the logged fingerprint matches fingerprint_key of the key I sent. A correct key returned 200.

Scope note

This is a logging-only change; auth behavior is unchanged (a bad key still gets a 401). The other items in #1440 are design questions (open setup when no key is configured, the key being readable in the frontend, the session cookie's Secure flag), so I left those alone. Happy to take any of them as separate follow-ups if you confirm the intended behavior.

verify_api_key logged the rejected key verbatim at WARNING, writing the
client's secret into server.log on every failed auth (a mistyped or
non-ASCII key from jundot#1719 leaks the credential).

Add fingerprint_key to admin/auth.py (truncated SHA-256, surrogatepass
encoding matching compare_keys) and log the fingerprint instead, so
repeated rejections of the same key stay correlatable without exposing
the secret.

Item 4 of jundot#1440
@jundot

jundot commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Thanks, this addresses item 4 of #1440 cleanly. The change stays on the common rejected-key path, preserves auth behavior, and logs only a stable fingerprint instead of the submitted secret. CI is green and I do not see a regression risk here. Since this is still marked draft, I'll wait until you mark it ready before merging.

@richgoodson richgoodson marked this pull request as ready for review June 9, 2026 10:47
@jundot

jundot commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Thanks for marking this ready. I rechecked the PR, and the scope still looks right: the rejected-key path now logs only a stable fingerprint, while auth behavior and both Bearer/x-api-key handling stay unchanged. The added tests cover the fingerprint helper and the dependency-level log behavior, including non-ASCII and lone-surrogate inputs, and CI is green. This looks good to me, and I am going to merge it.

@jundot jundot merged commit 1b0b80a into jundot:main Jun 10, 2026
4 checks passed
@richgoodson richgoodson deleted the fix/1440-redact-rejected-key-log branch June 11, 2026 02:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants