-
Notifications
You must be signed in to change notification settings - Fork 4
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
introduces per-user API tokens via 'apikey: true' #30
base: master
Are you sure you want to change the base?
Conversation
This commit introduces a rudimentary approach to assigning API keys on a per-user basis (rather than one global plain-text environment variable). **Generating an API Key** When making a `POST` request to the `/_users/` endpoint the inclusion of the following in the request body will generate an API key for the user: ``` POST /_users/ { "apikey": true, "auth": "admin", "provider": "google", "username": "[email protected]" } ``` The response will look like this. _Note: This is the only opportunity to retrieve the generated key. Keys are hashed in the database._ ```js { "_ref": "/_users/dGVzdEBleGFtcGxlLmNvbUBnb29nbGU=", "apikey": "dGVzdEBleGFtcGxlLmNvbUBnb29nbGU=:Z8EVBDN-M1T4EED-NH93XNJ-8J1374R", "auth": "admin", "provider": "google", "username": "[email protected]" } ``` **Revoking an API Key** To remove a user's key `POST` again with `apikey: false`: ``` POST /_users/ { "apikey": false, "auth": "admin", "provider": "google", "username": "[email protected]" } ``` The response will look like this. ```js { "_ref": "/_users/dGVzdEBleGFtcGxlLmNvbUBnb29nbGU=", "apikey": null, "auth": "admin", "provider": "google", "username": "[email protected]" } ``` --- In addition to per-user API keys, this commit introduces a new environment variable `CLAY_DISABLE_GLOBAL_ACCESS_KEY`. When set to a "true" value (`t`, `true`, `1`) _only_ user-level keys will work. This provides a "single-user-mode"-esq toggle for emergency recovery, allows Clay sites to run in a secure mode, but maintains backward compatibility for old API environment-based API keys where required or where convenient.
Rather than having a variable to disable the global access key, this commit disables the global API key when `CLAY_ACCESS_KEY` is set to an empty value (or not set at all).
}); | ||
|
||
afterAll(() => { | ||
process.env.CLAY_ACCESS_KEY = OLD_ACCESS_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.
not sure i understand what OLD_ACCESS_KEY is doing here, is it insufficient to just set process.env.CLAY_ACCESES_KEY
as in L24 above?
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.
This is really just a pattern to preserve the original values of the environment before the suite was executed.
I think ideally we'd mock out the whole process.env
for tests for reproducibility, but chose to stick close to what we had for this PR.
* @returns {boolean} | ||
*/ | ||
function isValidAPIKey(user, apikey) { | ||
return bcrypt.compareSync(apikey, user.apikey); |
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.
We might want to go with bcrypt.compare()
to keep from blocking other requests. I'm not sure why were doing hashSync()
.
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.
Yeah good call, I'll dig into using the async methods instead.
This commit introduces a rudimentary approach to assigning API keys on
a per-user basis (rather than one global plain-text environment
variable).
Generating an API Key
When making a
POST
request to the/_users/
endpoint the inclusionof the following in the request body will generate an API key for the
user:
The response will look like this. Note: This is the only opportunity
to retrieve the generated key. Keys are hashed in the database and
the hashed values are excluded from the GET API.
Revoking an API Key
To remove a user's key
POST
again withapikey: false
:The response will look like this.
In addition to per-user API keys, this commit introduces a newenvironment variableCLAY_DISABLE_GLOBAL_ACCESS_KEY
. When set to a"true" value (t
,true
,1
) only user-level keys will work.Edit: I replaced the
CLAY_DISABLE_GLOBAL_ACCESS_KEY
idea with a simpler method.Set
CLAY_ACCESS_KEY
to a value to enable the global access key.Unset
CLAY_ACCESS_KEY
to disable it.This provides a "single-user-mode"-esq toggle for emergency recovery,
allows Clay sites to run in a secure mode, but maintains backward
compatibility for old API environment-based API keys where required or
where convenient.