[1/n] Add id column on tokens and sessions#8137
Merged
david-crespo merged 13 commits intomainfrom Jun 3, 2025
Merged
Conversation
david-crespo
commented
May 12, 2025
48c4c68 to
7f377d8
Compare
david-crespo
commented
May 13, 2025
| primary_key = String, // token | ||
| primary_key = { uuid_kind = AccessTokenKind }, | ||
| roles_allowed = false, | ||
| polar_snippet = FleetChild, |
Contributor
Author
There was a problem hiding this comment.
I'm realizing FleetChild will probably have to change.
david-crespo
commented
May 20, 2025
ce269ce to
6fbe688
Compare
7 tasks
id column on tokens and sessionsid column on tokens and sessions
This was referenced May 27, 2025
6fbe688 to
a4d0d74
Compare
a4d0d74 to
6f16cfe
Compare
hawkw
reviewed
Jun 2, 2025
Member
hawkw
left a comment
There was a problem hiding this comment.
Overall, this makes sense to me. I had some minor nitpicks and style suggestions.
Contributor
Author
hawkw
approved these changes
Jun 2, 2025
Member
hawkw
left a comment
There was a problem hiding this comment.
Lovely, thanks for addressing my suggestions!
david-crespo
added a commit
that referenced
this pull request
Jun 4, 2025
Closes #2302. Built on top of #8137, but doesn't really rely on much in there. Implementing [RFD 570](https://rfd.shared.oxide.computer/rfd/0570). - [x] Add `silo_settings` table with nullable device token expiration (seconds) column. Null setting means no max - Also populate this table with null maxes for all existing silos - [x] Follow behavior of quotas table: create silo settings entry on silo create, delete it on silo delete - [x] View and update settings endpoints at `/v1/settings` with all necessary plumbing - Following RFD 570, these are silo-scoped endpoints, only accessible to users inside the silo, as opposed to, for example, fleet operators being able to set it for any silo - [x] Users don't set token expiration directly yet — at token create time, if the current silo has its max set, the token gets an expiration timestamp based on that max. Otherwise the token does not expire - [x] Test that trying to set a negative or 0 TTL 400s - [x] Fix authz tests and verify endpoint tests - [x] Bikeshed endpoint paths, operation IDs, property names, etc
david-crespo
added a commit
that referenced
this pull request
Jun 4, 2025
Built on top of #8137 and #8214. This is only for a user to list and delete their own tokens. It doesn't quite match RFD 570, which says `/v1/device-tokens` instead of `/v1/me/access-tokens`, but it feels good under `/v1/me`, and after trying to make the UI too, I think "access tokens" is much more intuitive. If I stick with this, I will update RFD 570 to match. ~~I'm not sure about the path `/v1/device-tokens` — in the API we call them `Device Access Tokens`. I think `/v1/access-tokens` might be more intuitive because the `device` is sort of an implementation detail, it refers to the OAuth device auth flow, which we are using. In practice, the user just gets a token with the CLI and pastes a code into the web UI and they don't have to think too much about it, so exposing that detail in the name might not be worth it.~~ Went with `/v1/me/access-tokens`. - [x] Basic token list and delete - [x] Basic integration tests - [x] Finalize endpoint paths - [x] Figure out authz story - Went with restricting datastore functions to current actor for now
david-crespo
added a commit
that referenced
this pull request
Jun 4, 2025
Closes #8147. Built on #8137, #8214, and #8227. This is pretty straightforward, I think. The user gives us a TTL in seconds at token request time. We store it on the request row. When they come back in the later step to confirm the code and generate the token, we retrieve the TTL, validate that it is less than the silo max (if one is set), and we use it to generate the `time_expires` timestamp, which cannot be changed later. One slightly surprising bit is that we can't validate the TTL against the silo max at initial request time because we don't have any idea what silo the user is associated with until the confirm step. So probably want to make sure we are handling TTL validation errors nicely in the web console, because I think that's where they will show up.
david-crespo
added a commit
that referenced
this pull request
Jun 4, 2025
Built on top of #8231. Fix for an issue with the internals of session expiration discussed in #8137 (comment). When I added ID primary keys to sessions and tokens, I changed the session delete method on the Session trait to operate by ID as well, and that meant a more complex authz situation compared to deleting by token. A bearer token is its own authz, at least according to the implicit policy we decided on. When I changed it to delete by ID, I made the delete function (now removed in this PR) use the user ID from the `opctx` to filter tokens to ensure that users could only delete their own sessions. The problem is that the `opctx` used in that case is the external authenticator op context, which has its own special actor that is distinct from the user in question. This means we would never actually delete a token this way because the query would always come up empty. This is not actually a problem from a correctness point of view because on subsequent requests we always check the expiration time on the session we pull out of the DB anyway. But it does mean that we probably end up with a lot more sessions piling up in the DB than we otherwise would. Not a big deal either way, but I feel more comfortable having it keep working the way it has worked for several years. It's also nice that we are deleting some app code here and replacing it with a test for a behavior that was previously untested. (I added the test in the first commit and confirmed that it fails without the changes from the second commit.)
This was referenced Aug 8, 2025
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #8139. Token IDs are used in #8227 and #8231 for token CRUD.
WIP. Everything compiles and existing tests work, but we are not yet testing retrieval by ID and we need to think about authz checks on the datastore functions for retrieving tokens and sessions by token string.
This PR would be a lot shorter if not for the fact that the
tokencolumn was the primary key on both tables, so adding theidrequires a bunch of migration steps to change the primary key. There were also a lot of changes to code and tests around making things ID-centric instead of token-centric.idcol and changing primary key to thatTypedUuidto session and token DB modelsauthz_resource!andlookup_resource!calls for new primary keySessiontrait methods to useidinstead oftokenFakeSessionimplementations (one for unit tests, one for integration tests) to a) track sessions in aVecinstead of aHashMapwith token keys