Skip to content

Commit

Permalink
perf(api-keys): move from encrypted to hashed api key
Browse files Browse the repository at this point in the history
  • Loading branch information
bodymindarts committed Jan 12, 2024
1 parent 16ab555 commit 471748e
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 8 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE identity_api_keys
ADD COLUMN hashed_key BYTEA UNIQUE DEFAULT gen_random_bytes(256);
35 changes: 31 additions & 4 deletions core/api-keys/src/identity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ impl Identities {
) -> Result<(IdentityApiKey, ApiKeySecret), IdentityError> {
let code = Alphanumeric.sample_string(&mut rand::thread_rng(), 64);
let record = sqlx::query!(
r#"INSERT INTO identity_api_keys (encrypted_key, identity_id, name, expires_at, read_only)
VALUES (crypt($1, gen_salt('bf')), $2, $3, $4, $5) RETURNING id, created_at"#,
r#"INSERT INTO identity_api_keys (hashed_key, encrypted_key, identity_id, name, expires_at, read_only)
VALUES (digest($1, 'sha256'), crypt($1, gen_salt('bf')), $2, $3, $4, $5)
RETURNING id, created_at"#,
code,
identity_id as IdentityId,
name,
Expand Down Expand Up @@ -111,7 +112,7 @@ impl Identities {
FROM identities i
WHERE k.identity_id = i.id
AND k.revoked = false
AND k.encrypted_key = crypt($1, k.encrypted_key)
AND k.hashed_key = digest($1, 'sha256')
AND (k.expires_at > NOW() OR k.expires_at IS NULL)
RETURNING k.id, i.subject_id, k.read_only
)
Expand All @@ -128,7 +129,33 @@ impl Identities {
record.read_only,
))
} else {
Err(IdentityError::NoActiveKeyFound)
// look up by encrypted key and set hashed_key
let record = sqlx::query!(
r#"WITH updated_key AS (
UPDATE identity_api_keys k
SET last_used_at = NOW(), hashed_key = digest($1, 'sha256')
FROM identities i
WHERE k.identity_id = i.id
AND k.revoked = false
AND k.encrypted_key = crypt($1, k.encrypted_key)
AND (k.expires_at > NOW() OR k.expires_at IS NULL)
RETURNING k.id, i.subject_id, k.read_only
)
SELECT id, subject_id, read_only FROM updated_key"#,
code
)
.fetch_optional(&self.pool)
.await?;

if let Some(record) = record {
Ok((
IdentityApiKeyId::from(record.id),
record.subject_id,
record.read_only,
))
} else {
Err(IdentityError::NoActiveKeyFound)
}
}
}

Expand Down

0 comments on commit 471748e

Please sign in to comment.