Skip to content

Conversation

@gwossum
Copy link
Member

@gwossum gwossum commented Feb 6, 2025

Add optional token hashing with --use-hashed-tokens command line option.

@gwossum gwossum added kind/feature area/2.x OSS 2.0 related issues and PRs labels Feb 6, 2025
@gwossum gwossum self-assigned this Feb 6, 2025
Copy link
Contributor

@davidby-influx davidby-influx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A variety of smaller issues. I will need to review this again to fully understand the larger changes.

Copy link
Contributor

@davidby-influx davidby-influx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My usual add more context to error and log messages and a few more substantive questions and suggestions

Copy link
Contributor

@davidby-influx davidby-influx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All changes pertain to comments, but important one is whether to delete or include a commented out code section

@gwossum gwossum force-pushed the gw/edge306/token_hashing branch from 15f8e92 to 6aa2d1a Compare February 25, 2025 21:42
Copy link

@devanbenz devanbenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few comments mostly about extra safety checks and some error messaging. I've been able to get about half way through the PR. Going to step away for a minute to take a little brain break and then finish up the rest of the PR for my first pass.

Copy link

@devanbenz devanbenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a few more comments to storage_authorization.go I noticed that a bunch of my comments for the require.NoError(..) is similar to what david commented so my apologies for that :P

Copy link

@devanbenz devanbenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding in a few more comments

devanbenz
devanbenz previously approved these changes Feb 28, 2025
Copy link

@devanbenz devanbenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to pick back up my review next week for a second pass. Consider this first pass finished up.

@devanbenz devanbenz self-requested a review February 28, 2025 19:00
@devanbenz devanbenz dismissed their stale review February 28, 2025 19:00

Dismissing

Copy link

@devanbenz devanbenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finished reading through this code, everything looks fine to me after that pass. Please let me know when you merge in main and require a second look over.

@gwossum gwossum force-pushed the gw/edge306/token_hashing branch from a3c28e7 to fc74353 Compare July 23, 2025 22:43
@gwossum
Copy link
Member Author

gwossum commented Aug 25, 2025

Claude's analysis of potential information leakage in error messages:

  With the understanding that only system administrators have log access, there is essentially NO information leakage risk from error messages in this implementation.

  Why No Risk

  1. Administrators are trusted: System admins already have:
    - Direct database access
    - Ability to view/modify all authorizations
    - Access to configuration and secrets
    - Root/administrative system access
  2. Logs need debugging detail: For administrators, detailed error messages are beneficial, not risky:
    - They need to diagnose issues quickly
    - Token IDs and descriptions help identify problematic authorizations
    - Hash variant information aids in migration troubleshooting
  3. No sensitive data logged: Even for admins, the code correctly:
    - Never logs actual token values
    - Never logs hashed token values
    - Only logs operational metadata

  Current Error Messages Are Appropriate

  Examples like:
  - "error hashing token for token %d (%s): %w" - Helps admins identify which token failed
  - "found authorization without any token set during hashed token migration" - Alerts admins to data integrity issues
  - "hashing raw token failed (variant=%s): %w" - Helps debug algorithm configuration issues

  These provide exactly the right level of detail for administrative troubleshooting.

  Final Assessment

  Information leakage risk: NONE

  The error messages are appropriately designed for their audience (system administrators) and contain no sensitive information. The implementation correctly balances:
  - Detailed internal errors for admin debugging
  - Generic external errors for security
  - No logging of actual sensitive values

  No changes needed - the error handling is well-implemented for a production system.

Copy link

@devanbenz devanbenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving two comments, still finishing up the review.

Copy link
Contributor

@davidby-influx davidby-influx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few remaining suggestions. What a huge amount of work!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a general question: do we have context for all the startup errors?

  • Opening the KV store
  • NewAuthorizationHasher
  • authorization.NewStore
  • etc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took a while, but I think there's good context for everything in authorization/authorization.goand authorization/storage_authorization.go

@devanbenz
Copy link

devanbenz commented Nov 17, 2025

I tested everything locally and it all seems fine. I did notice, as outlined by your comment here: https://github.com/influxdata/influxdb/pull/25982/files#diff-05dfd885ddd66163be3e6ac7416f3b6326f186d236cba26153bd790bc93c880dR51, that starting up influxd without --use-hashed-tokens does lead to new tokens not being hashed. Do you think it would be beneficial to add some sort of warning log or info log upon token creation or startup if there are already hashed tokens? Just informing the user that influxd may not be running with token hashing enabled when it was previously enabled?

@gwossum
Copy link
Member Author

gwossum commented Nov 19, 2025

I tested everything locally and it all seems fine. I did notice, as outlined by your comment here: https://github.com/influxdata/influxdb/pull/25982/files#diff-05dfd885ddd66163be3e6ac7416f3b6326f186d236cba26153bd790bc93c880dR51, that starting up influxd without --use-hashed-tokens does lead to new tokens not being hashed. Do you think it would be beneficial to add some sort of warning log or info log upon token creation or startup if there are already hashed tokens? Just informing the user that influxd may not be running with token hashing enabled when it was previously enabled?

During normal operation, there is no way to "downgrade" a hashed token, so there is no need to log about unhashing a token. On startup, the hashed token can not be unhashed because hashes are one-way. When a token is used, there is no attempt to store it as unhashed, even though this could be added. The only way to update a token is by sending a PATCH request to v2/authorizations, which does not allow changing the actual token value. Because of this, when an update is performed the at-rest storage of the token (hashed vs unhashed) can not be changed.

I think logging on startup that hashed tokens exist but hashed tokens are disabled is a good idea, though.

@philjb
Copy link
Contributor

philjb commented Nov 19, 2025

I'd be ok with using a helper for all the auth.Token != "" and auth.HashedToken != "" != "" checks.

if tokenUnset(auth.HashedToken) {

func tokenUnset(t string) bool {
    return t == ""
}

not essential, but the code makes assumptions about what the empty string means -- there's a comment about it so it is essentially a special type of token: an "unset one".

Copy link
Contributor

@philjb philjb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initial comments

Additionally, raw tokens are automatically migrated to hashed tokens if `--use-hashed-tokens` is configured.
Due to the schema changes, to use a version of InfluxDB without hashed token support, a manual downgrade using
`influxd downgrade` must be run. Any tokens stored as hashed tokens will be unusable by the old version of InfluxDB
and must be reset or recreated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth while to mention "or restored from an independent backup" ? or something like that?

@gwossum
Copy link
Member Author

gwossum commented Nov 19, 2025

I'd be ok with using a helper for all the auth.Token != "" and auth.HashedToken != "" != "" checks.

if tokenUnset(auth.HashedToken) {

func tokenUnset(t string) bool {
    return t == ""
}```

not essential, but the code makes assumptions about what the empty string means -- there's a comment about it so it is essentially a special _type_ of token: an "unset one". 

That's a good idea. I'll go ahead and implement it.

DestP: &o.UseHashedTokens,
Flag: "use-hashed-tokens",
Default: o.UseHashedTokens,
Desc: "enable token hashing",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so terse it borders on inaccurate for everything this flag controls.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about enable storing hashed API tokens on disk (improves security, but prevents downgrades to < 2.8)?

Add optional token hashing with `--use-hashed-tokens` command line option.
Create duplicate tokens from being created. This is a bug introduced
earlier in this PR. Also improve tests so they detect the bug and use
testify throughout.
Fix a bug that only allowed hashed tokens to be looked up if they used the
currently active hashing algorithm. Also added tests for configuration
migration scenarios (enabling and disabling hashing, changing hashing scheme).
Address PR issues on comments, error handling, and add final token
matching check in `Store.GetAuthorizationByToken`.
Changes in addition to minor cleanups:
- `authentication.Store` can now log info and warnings
- Improved logic in `UpdateAuthorization` when both Token and HashedToken
  are set. Added supporting test cases.
Add tests for misuses of NewAuthorizationHasher and improve an error
message.
Update outdated comment regarding PHC format attack.
- In Store.autogenerateHasher, avoid modifying foundVariants.
- Improve comment for Hasher.HashWithSalt
- Removed `authResponse.HashedToken` field
- Improved error messages, log messages, and comments
- Improved error propagation
- Improve description of `--use-hashed-tokens` command line parameter
- Removed dead code
- Implemented test to make sure hashed version of tokens can not be
  presented for authentication
@gwossum gwossum force-pushed the gw/edge306/token_hashing branch from f35ac5b to d1b3e1b Compare November 20, 2025 19:41
@gwossum gwossum marked this pull request as ready for review November 20, 2025 19:42
Copy link
Contributor

@philjb philjb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gwossum gwossum merged commit b74507b into main-2.x Nov 20, 2025
25 checks passed
@gwossum gwossum deleted the gw/edge306/token_hashing branch November 20, 2025 20:18
@davidby-influx davidby-influx linked an issue Nov 21, 2025 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/2.x OSS 2.0 related issues and PRs kind/feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Operator Token Privilege Escalation

5 participants