Project

General

Profile

Actions

Feature #43938

closed

Track last usage of API and Atom access keys

Added by Vincent Robert 21 days ago. Updated 2 days ago.

Status:
Closed
Priority:
Normal
Category:
REST API
Target version:
Resolution:
Fixed

Description

Hello

As a first step toward #43881, this patch records and displays the last time each user's API key was used.

Problem:
There is currently no way to know if an API key has ever been used, or when it was last used.
This makes it impossible to identify stale or potentially compromised keys.

Proposal:
- Add a last_used_on column to the tokens table
- Update it on every successful API authentication (header, query parameter, or HTTP Basic)
- Display "Last used: X ago" / "Never used" in the account sidebar, next to the creation date

Notes:
- The update is a single UPDATE by unique index — negligible overhead per request
- Backward compatible: existing keys get null until first use


Files


Related issues

Related to Redmine - Feature #43881: Strengthen API authentication: API tokens with expiration, scopes, rate limiting and audit loggingNewActions
Actions #1

Updated by Vincent Robert 21 days ago

  • Related to Feature #43881: Strengthen API authentication: API tokens with expiration, scopes, rate limiting and audit logging added
Actions #2

Updated by Holger Just 21 days ago

This would write to the database on each and every API request which would cause a lot of write traffic and lock contention on the database table.

This should at least be throttled, similar to #28952 and #29041.

Actions #3

Updated by Vincent Robert 21 days ago

Ok. I have updated the patch, so the value is updated only once per minute.

Actions #4

Updated by Vincent Robert 21 days ago

  • File deleted (0001-track-api-key-last-used-on.patch)
Actions #5

Updated by Holger Just 21 days ago

This still issues the update query and thus may issue database locks. I think a better design here would be to use Token.find_token to get a hold of the actual object. From that, we can update the expiration date if required and return the user. That way, there is no update query at all unless actually required.

Alternatively, it may be a good idea to integrate the update of the last_used_on timestamp into the Token query methods directly. That way, the update would be naturally available to other token types too (e.g. the atom keys).

And with that being said, it seems that we already use the updated_on timestamp on session tokens to track when the session was last used. This serves quite a similar similar purpose than what you proposed here with the new last_used_on field. It may be useful to combine both of these features. We could also just bump the updated_on timestamp of the api token on use, similar to what is done for the session tokens min User.verify_session_token. Then, we would not need the separate database field at all.

Actions #6

Updated by Vincent Robert 20 days ago

You're right. Here is an updated version addressing these points.

Instead of introducing a new last_used_on field, the patch now reuses the existing updated_on timestamp. No migration is required.
All token types (API keys, atom/feeds) benefit from it.
The update is skipped in Ruby if updated_on is less than a minute-old.

Actions #7

Updated by Marius BĂLTEANU 19 days ago

  • Status changed from New to Resolved
  • Assignee set to Marius BĂLTEANU
  • Target version set to 7.0.0
  • Resolution set to Fixed

Patch committed, thanks!

Actions #8

Updated by Marius BĂLTEANU 16 days ago

  • Subject changed from Track last usage of API access keys to Track last usage of API and Atom access keys
I made some changes:
  • generalized the labels in order to reuse them across tokens
  • show the last usage of Atom access key

I will close this issue once I update the tests for Atom access key.

Actions #9

Updated by Marius BĂLTEANU 4 days ago

  • Status changed from Resolved to Closed

Add tests and moved the token usage logic into the model.

Actions #10

Updated by Go MAEDA 4 days ago

  • Status changed from Closed to Reopened

The change r24614 causes test failures.

Failure:
MyControllerTest#test_my_account_should_show_last_used_api_key [test/functional/my_controller_test.rb:600]:
--- expected
+++ actual
@@ -1 +1 @@
-/API access key created/
+"Login: jsmith Created: 07/20/2006 02:32 AM" 
.
Expected 0 to be >= 1.

bin/rails test test/functional/my_controller_test.rb:594

.....................................F

Failure:
MyControllerTest#test_my_account_should_show_never_used_api_key [test/functional/my_controller_test.rb:588]:
--- expected
+++ actual
@@ -1 +1 @@
-/API access key created/
+"Login: jsmith Created: 07/20/2006 02:32 AM" 
.
Expected 0 to be >= 1.

bin/rails test test/functional/my_controller_test.rb:582
Actions #11

Updated by Marius BĂLTEANU 2 days ago

  • Status changed from Reopened to Closed
Actions

Also available in: Atom PDF