TokenRedisStore#

class gafaelfawr.storage.token.TokenRedisStore(storage, slack_client, logger)#

Bases: object

Stores and retrieves token data in Redis.

Tokens are stored with the key of the token as the Redis key and the data of the token as encrypted JSON, including the secret portion of the token. To retrieve a token, the caller must provide the full token and the secret in the token must match the secret retrieved from Redis.

This setup means that an attacker who can list the keys in Redis cannot use those keys directly as tokens and still needs access to the stored Redis data plus the decryption key to be able to reconstruct a token.

Parameters:

Methods Summary

delete(key)

Delete a token from Redis.

delete_all()

Delete all stored tokens.

get_data(token)

Retrieve the data for a token from Redis.

get_data_by_key(key)

Retrieve the data for a token from Redis by its key.

get_data_by_key_unchecked(key)

Retrieve the data for a token by key without catching errors.

list()

List all token keys stored in Redis.

store_data(data)

Store the data for a token.

Methods Documentation

async delete(key)#

Delete a token from Redis.

This only requires the token key, not the full token, so that users can delete tokens for their account without needing possession of the token.

Parameters:

key (str) – The key portion of the token.

Returns:

True if the token was found and deleted, False otherwise.

Return type:

bool

async delete_all()#

Delete all stored tokens.

Return type:

None

async get_data(token)#

Retrieve the data for a token from Redis.

Doubles as a way to check the validity of the token.

Parameters:

token (Token) – The token.

Returns:

The data underlying the token, or None if the token doesn’t exist or is not valid.

Return type:

TokenData or None

async get_data_by_key(key)#

Retrieve the data for a token from Redis by its key.

This method allows retrieving a working token while bypassing the check that the caller is in possession of the secret, and therefore must never be used with user-supplied keys.

Parameters:

key (str) – The key of the token.

Returns:

The data underlying the token, or None if the token doesn’t exist or is not valid.

Return type:

TokenData or None

async get_data_by_key_unchecked(key)#

Retrieve the data for a token by key without catching errors.

This method allows retrieving a working token while bypassing the check that the caller is in possession of the secret, and therefore must never be used with user-supplied keys. It raises exceptions if the key is invalid rather than pretending the token doesn’t exist, making it suitable for lower-level audits.

Parameters:

key (str) – The key of the token.

Returns:

The data underlying the token, or None if the token doesn’t exist.

Return type:

TokenData or None

Raises:

safir.redis.DeserializeError – Raised if the data stored in Redis is invalid.

async list()#

List all token keys stored in Redis.

Returns:

The tokens found in Redis (by looking for valid keys).

Return type:

list of str

async store_data(data)#

Store the data for a token.

Parameters:

data (TokenData) – The data underlying that token.

Return type:

None