Skip to main content

Momento tokens for short-lived permissions

Tokens are short-lived, limited-scope values intended to be used in temporary situations like a user's session. Software lifecycle events like a user login often result in the issuing of a token only valid for the duration of that session.

tip

Not sure if you should be using an API key or a token? Check out our authentication page for all the details!

Tokens cannot be refreshed. So once it expires, it's gone forever. You'll be responsible for creating and issuing a new one if the session continues.

A Momento token allows access to data plane API operations only. The user is unable to do control plane operations like creating, deleting, or flushing a cache.

A user with a fully privileged token will be able to perform the following actions:

  • Add/edit/delete cache items in any cache
  • Publish and subscribe to any topic in any cache
  • Increment cache values via the increment API in any cache

It's up to you to limit the access of a token based on your system requirements.

Creating a token

Unlike our API keys, the only way to create a token is through code. You cannot create them through the Momento console.

Below are some examples to create tokens with different sets of permissions:

// Generate a disposable token with read-write access to a specific key in one cache
const oneKeyOneCacheToken = await authClient.generateDisposableToken(
DisposableTokenScopes.cacheKeyReadWrite('squirrels', 'mo'),
ExpiresIn.minutes(30)
);
if (oneKeyOneCacheToken instanceof GenerateDisposableToken.Success) {
console.log('Generated a disposable API key with access to the "mo" key in the "squirrels" cache!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${oneKeyOneCacheToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${oneKeyOneCacheToken.expiresAt.epoch()}`);
} else if (oneKeyOneCacheToken instanceof GenerateDisposableToken.Error) {
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${oneKeyOneCacheToken.errorCode()}: ${oneKeyOneCacheToken.toString()}`
);
}

// Generate a disposable token with read-write access to a specific key prefix in all caches
const keyPrefixAllCachesToken = await authClient.generateDisposableToken(
DisposableTokenScopes.cacheKeyPrefixReadWrite(AllCaches, 'squirrel'),
ExpiresIn.minutes(30)
);
if (keyPrefixAllCachesToken instanceof GenerateDisposableToken.Success) {
console.log('Generated a disposable API key with access to keys prefixed with "squirrel" in all caches!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${keyPrefixAllCachesToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${keyPrefixAllCachesToken.expiresAt.epoch()}`);
} else if (keyPrefixAllCachesToken instanceof GenerateDisposableToken.Error) {
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${keyPrefixAllCachesToken.errorCode()}: ${keyPrefixAllCachesToken.toString()}`
);
}

// Generate a disposable token with read-only access to all topics in one cache
const allTopicsOneCacheToken = await authClient.generateDisposableToken(
TokenScopes.topicSubscribeOnly('squirrel', AllTopics),
ExpiresIn.minutes(30)
);
if (allTopicsOneCacheToken instanceof GenerateDisposableToken.Success) {
console.log('Generated a disposable API key with access to all topics in the "squirrel" cache!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${allTopicsOneCacheToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${allTopicsOneCacheToken.expiresAt.epoch()}`);
} else if (allTopicsOneCacheToken instanceof GenerateDisposableToken.Error) {
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${allTopicsOneCacheToken.errorCode()}: ${allTopicsOneCacheToken.toString()}`
);
}

// Generate a disposable token with write-only access to a single topic in all caches
const oneTopicAllCachesToken = await authClient.generateDisposableToken(
TokenScopes.topicPublishOnly(AllCaches, 'acorn'),
ExpiresIn.minutes(30)
);
if (oneTopicAllCachesToken instanceof GenerateDisposableToken.Success) {
console.log('Generated a disposable API key with access to all topics in the "squirrel" cache!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${oneTopicAllCachesToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${oneTopicAllCachesToken.expiresAt.epoch()}`);
} else if (oneTopicAllCachesToken instanceof GenerateDisposableToken.Error) {
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${oneTopicAllCachesToken.errorCode()}: ${oneTopicAllCachesToken.toString()}`
);
}

For detailed information on creating a token, please refer to the API reference page.

Expiration

Momento tokens are required to have an expiration time. The maximum expiration time for a token is 1 hour. When the token expiration time elapses, you will be required to create a new one.

If you attempt to make a call with an expired token, you will receive a AUTHENTICATION_ERROR response indicating the provided credentials could not connect to the service.

tip

Tokens cannot be refreshed. So once it expires, it's gone forever. You'll be responsible for creating and issuing a new one if the session continues.

Use cases

These tokens are a great fit for the following use cases:

  • Using Momento for front-end development
  • Communicating with IoT devices
  • Issuing temporary access to specific resources
  • Providing credentials to users on login

Data restriction

A common use case for a token is to limit access to only a small subset of resources. Not only can you limit capabilities, like providing a token with read-only access, but you can also scope it to individual cache items or topics.

To get a full understanding of what you can do with data restriction, check out our permissions page.