-
Notifications
You must be signed in to change notification settings - Fork 5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a DELETE endpoint for API Keys #37051
Conversation
Passing run #1266 ↗︎
Details:
Review all test suite changes for PR #37051 ↗︎ |
a5a89d4
to
8a9f0f9
Compare
d53d92c
to
9b25c1a
Compare
Current dependencies on/for this PR:
This stack of pull requests is managed by Graphite. |
9b25c1a
to
90cb001
Compare
45993e7
to
ecce8b4
Compare
90cb001
to
7b6fb13
Compare
ecce8b4
to
0964f09
Compare
7b6fb13
to
a8f0183
Compare
What's the advantage of archiving API keys instead of deleting the API Key and the associated user? Normal users can only be archived, not deleted, but api-key users don't necessarily have to have the same constraint since they're more of an internal mechanism than actual users. And there's the slight risk that a bug in the future could allow deactivated API keys to still be used for auth. I know you've added checks to prevent that but it's still a potential risk if we're not allowing API keys to be fully deleted. Don't have a strong opinion necessarily, but just want to make sure we have a good justification for the approach here. |
Deleting a user would cause other issues - for example, if an API key user creates a dashboard, then deleting that user would break the
This is a good point to consider. What would you think of regenerating the API key as part of "deletion"? That way any existing key becomes unusable even if there's a bug that allows auth with a "deleted" key. |
Gotcha. Yeah I'd be in favor of either:
|
One additional point I want to consider is auditability. Say
We'd have an audit log that showed that User 123, with type I think this makes me lean towards the first option - overwriting the ApiKey with a Does that sound reasonable? Another option would be to add EDIT: I'm going with option 2, deleting the ApiKey but leaving the User: https://metaboat.slack.com/archives/C064EB1UE5P/p1703284432369899?thread_ts=1703183375.589429&cid=C064EB1UE5P |
a8f0183
to
cc9db8b
Compare
f230bda
to
7d65dcd
Compare
src/metabase/api/api_key.clj
Outdated
(let [api-key (-> (t2/select-one :model/ApiKey id) | ||
(t2/hydrate :group_name))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a huge deal, but might be worth wrapping this in check-404
. Even though it's a deletion endpoint, we should probably return a 404 if the caller is trying to delete something that already doesn't exist.
The User update call below would also error in this case anyway, so probably better to catch that at the start and error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call. I'm also going to add this check to the PUT
endpoints.
src/metabase/api/api_key.clj
Outdated
(events/publish-event! :event/api-key-delete | ||
{:object api-key | ||
:user-id api/*current-user-id*}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's another case where I don't think the publish-event!
call should be in the transaction, since we don't know what downstream DB calls are generated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, thanks for noticing this - sorry about that!
src/metabase/api/api_key.clj
Outdated
(events/publish-event! :event/api-key-delete | ||
{:object api-key | ||
:user-id api/*current-user-id*}) | ||
(present-api-key api-key)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a specific reason we need to return the API key after it's been deleted? If not, you could just return a 204 (api/generic-204-no-content
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, done!
9a63671
to
265e21e
Compare
265e21e
to
1d1ee6c
Compare
When the endpoint is hit, we delete the ApiKey from the database. The user is left behind to ensure that we don't break foreign keys, and to enhance auditability.
1d1ee6c
to
6e93a7a
Compare
@johnswanson Did you forget to add a milestone to the issue for this PR? When and where should I add a milestone? |
Don't actually delete them from the database (to keep the invariant that a user with an
:api-key
type will always have an associated ApiKey). Just mark them as:archived
, and:make them invisible to the count endpoint
make them invisible to the list endpoint
make them not work for authentication