This commit is contained in:
Joe 2026-02-02 12:08:47 -06:00
parent a9b4f8e83b
commit e6efc04756
8494 changed files with 495610 additions and 0 deletions

View file

@ -0,0 +1,170 @@
---
title: Manage API keys
description: Explains how to create API keys and add permissions to use Open Cloud web APIs for your experience.
---
Open Cloud authenticates and authorizes API access with the use of API keys,
which allow you to add granular permissions and security control for accessing
and utilizing certain resources in your experience, such as data stores and
places.
All Open Cloud APIs require you to create an API key with valid permissions and
include an `x-api-key` header in your request, which allows the application to
authenticate to Open Cloud on your behalf.
## Create API keys
<Alert severity="warning">
All references to API keys in the text below refer to user-owned keys.
</Alert>
You can create and configure API keys to access your resources. An API key's access is determined by the permissions of the user who owns it. This means it can generally access any resource the user has permissions for, including their individual experiences and any [group-owned](../../projects/groups.md) experiences where they have the appropriate role. Some scopes can be restricted to specific experiences, but not all.
For details on how to create API keys for managing group resources, see the [Create API keys for managing group-owned resources](#create-api-keys-for-managing-group-owned-resources) section below.
To create an API key:
1. In the [Creator Dashboard](https://create.roblox.com/dashboard/creations), go to the [API Keys](https://create.roblox.com/dashboard/credentials?activeTab=ApiKeysTab) page.
1. Click the **Create API Key** button.
1. Enter a unique name for your API key. Use a name that can help you recall the
purpose later, such as `PLACE_PUBLISHING_KEY` for publishing places to your
experience.
1. In the **Access Permissions** section, select an API from the **Select API
System** menu. Repeat this step if
you need to add multiple APIs to the key.
1. If applicable, select the experience that you want to access with the API key.
You can optionally disable **Restrict by Experience**. When disabled, your API key has access to all of your user-owned experiences and any group-owned experiences where you have the appropriate permissions, including any experiences you create in the future.
1. From the **Select Operations** dropdown, select the operations that you
want to enable for the API key.
Most operations in the [API reference](../index.md) include the required permission scopes. For example, the [flush memory store](/cloud/reference/MemoryStore#Cloud_FlushMemoryStore) operation requires the `universe.memory-store:flush` permission.
For a list of all scopes and the APIs they support, see [Scopes](../reference/scopes.md).
1. **(Optional)** In the **Security** section, explicitly restrict IP access to the key using [CIDR
notation](#cidr-format). You can find
the IP address of your local machine and add it to the **Accepted IP
Addresses** section along with additional IP addresses for those that need
access. If you don't have a fixed IP, or you are using the API key only in a
local environment, you can leave the `Restrict IP addresses` toggle unchecked to allow any IP to use your API key.
1. **(Optional)**: To add additional protection for your resources, set an expiration date for your key.
1. Click the **Save & Generate key** button.
1. Copy and save the API key string to a secure location, **not** a public repository for your code.
1. Verify the status of your API key on the
[API Extensions](https://create.roblox.com/dashboard/credentials) page of **Creator
Dashboard**.
<Alert severity="warning">
The API key string is equivalent to a password for your application. Never share it with untrusted parties, such as anyone outside of your development team.
</Alert>
## Create API keys for managing group-owned resources
An API key grants access to all resources the user account has permissions for, including personal experiences outside of the group. If you use your personal account's API key for group automation and that key is compromised, other resources you have access to are also at risk.
To prevent this, we **strongly recommend** creating a separate API key on a dedicated alternate account with access strictly limited to the target group. This new account dedicated for automation purposes should only be given access to the target group and granted the minimal permissions required for its task.
1. Create a new, dedicated Roblox account for your automation.
1. Invite the new account to your group.
1. Assign it a group role with the minimum permissions required for its task (e.g., only "Create and edit group experiences").
1. Log in to the new account and follow the steps in the section above to [create an API key](#create-api-keys).
1. Use the generated API key for group resource automation.
## Best Practices For Managing API Keys
API keys are sensitive credentials that should be kept secure to prevent unauthorized access to your data. Here are some best practices for managing API keys.
- **Create separate keys for each application**: Create separate API keys for each application or use case to isolate access and reduce the impact if a key is compromised.
- **Select the minimum permissions needed**: When configuring scopes, select the minimum permissions necessary for the key's intended use. For those scopes that allow you to restrict scope access by experience, limit access to only the specific experiences that are needed.
- **Use IP address restrictions**: Restrict API key access to specific IP addresses or CIDR ranges to prevent unauthorized usage from unknown locations. Do not use IP address restrictions when using your API key in Roblox places to ensure your key can be used with Roblox servers.
- **Set expiration dates**: For short-term use cases, configure expiration dates to automatically disable keys after a set period, reducing the risk if a key is compromised. Setting expiration dates is not recommended for longer-term use cases unless you have a key rotation process in place, as your automation can unexpectedly fail when the key expires.
- **Use dedicated alternate accounts for group resource management**: Use a dedicated account with minimal permissions for group resource management, as detailed in the [Create API keys for managing group-owned resources](#create-api-keys-for-managing-group-owned-resources) section.
- **Store API keys securely**: Never store API keys directly in your source code, version control systems, or scripts where they could be exposed. Use a secrets management system for storing and controlling access to your keys. In Roblox places, use a [Secrets Store](cloud-services/secrets).
- **Do not share API keys through public channels**: Never share API keys through public communication channels, forums, or social media. Only share keys through secure, private channels with trusted team members. Limit access to who you share your keys with to minimize the blast radius if a key is compromised.
## CIDR format
To further protect your resources, when [creating an API
key](#create-api-keys), specify IP addresses that can access the API key with
either normal IP addresses or using the [CIDR
notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation).
A CIDR IP address looks like a normal IP address except it ends with a slash and
a decimal that represents how many bits of the IP address are significant for
network routing:
- **Normal**: 192.168.0.0
- **CIDR**: 192.168.0.0/24
The former part is the IP address and the latter part is the **netmask**,
counting the bits of 1s in binary format. In the previous example, **24** means
**255.255.255.0** (24 1s) that allows all IPs between **192.168.0.0** and
**192.168.0.255**. Understanding CIDR format is particularly useful if you plan
to run your applications on a server.
## API key status
API keys initially have an active status, but they can become inactive over
their lifetime. To learn why an API key has changed status and how to return the
API key back to an active status, see the following table.
<Alert severity="warning"> If you or your group don't use or update an API key
for 60 days, it automatically expires, even if it doesn't have a set expiration
date. This reduces the risk of bad actors using old API keys. If you're no
longer using an API key, you should manually disable or delete it. </Alert>
<table>
<thead>
<tr>
<th>Status</th>
<th>Reason</th>
<th>Resolution</th>
</tr>
</thead>
<tbody>
<tr>
<td>Active</td>
<td>No issues. The user can use the key to authenticate API calls.</td>
<td>N/A</td>
</tr>
<tr>
<td>Disabled</td>
<td>The user disabled the key by disabling the <b>Enable Key</b> toggle.</td>
<td>Enable the <b>Enable Key</b> toggle.</td>
</tr>
<tr>
<td>Expired</td>
<td>The key's expiration date has passed.</td>
<td>Either remove or set a new expiration date.</td>
</tr>
<tr>
<td>Auto-Expired</td>
<td>The user hasn't used or updated the key in the past 60 days.</td>
<td>You can either disable then enable the <b>Enable Key</b> toggle, or you can update any of the key's properties, such as the name, description, or expiration date.</td>
</tr>
<tr>
<td>Revoked</td>
<td>For group keys only. The account that generated the key no longer has the sufficient access permission to manage the group's keys.</td>
<td>Click the <b>Regenerate Key</b> to get a new secret.</td>
</tr>
<tr>
<td>Moderated</td>
<td>A Roblox admin changed the key's secret for security reasons.</td>
<td>Click the <b>Regenerate Key</b> to get a new secret.</td>
</tr>
<tr>
<td>User Moderated</td>
<td>The account that generated the key is under moderation by Roblox.</td>
<td>Resolve the moderation issue on the account.</td>
</tr>
</tbody>
</table>

View file

@ -0,0 +1,206 @@
---
title: OAuth 2.0 app implementation
description: Introduces OAuth 2.0 authentication implementation.
---
Open Cloud supports the OAuth 2.0 authorization flow with and without
[PKCE](../../cloud/auth/oauth2-overview.md#authorization-code-flow-with-pkce),
depending on whether your clients are confidential or public.
- _Confidential clients_ are apps that are capable of keeping credentials
confidential, such as a website that can securely store and retrieve secrets on
its backend.
- _Public clients_ are apps that can't keep secrets, such as mobile
and web browser apps.
We recommend the OAuth 2.0 authorization code flow with PKCE for _all_ clients
and require it for public clients.
<Alert severity="warning">
Store the client secret in a secure place and never expose it to the public. Bad
actors can use it to impersonate your application.
</Alert>
To implement the authorization code flow, your app performs the following steps:
1. Generate a code verifier and code challenge (PKCE only). This lets you
include a challenge in your requests rather than the client secret, which
improves security.
1. Send a `GET` request to the authorization endpoint with the appropriate parameters.
1. Handle the authorization callback. After obtaining authorization, use the
authorization code from Roblox in a redirect request to the URL you specified
during app creation. Parse the authorization code for later use.
1. Send a `POST` request to the token endpoint with the authorization code. If
successful, you receive access and refresh tokens with which to make API
calls.
1. Call any Open Cloud API that supports OAuth 2.0 authentication based on the
reference documentation for the resources you want to access.
The following sections describe each step in greater depth.
## Generate a code challenge (for PKCE only)
Before initiating the authorization process, you need to generate a code
challenge from a code verifier. You can use libraries or built-in functions in
the programming language of your choice to create the code verifier, calculate
the hash, and perform Base64 encoding to generate the code challenge.
When creating the code verifier, only use unreserved characters, including
uppercase and lowercase letters (A-Z, a-z), decimal digits (0-9), hyphen (-),
period (.), underscore (\_), and tilde (~), with a minimum length of 43
characters and a maximum length of 128 characters.
The following example shows how to use Javascript to create a code verifier and
generate the code challenge using the SHA-256 hashing algorithm:
```javascript title="Generate Code Challenge"
const crypto = require('crypto');
// base64URL encode the verifier and challenge
function base64URLEncode(str) {
return str.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
// create sha256 hash from code verifier
function sha256(buffer) {
return crypto.createHash('sha256').update(buffer).digest(`base64`);
}
// create a random code verifier
var code_verifier = base64URLEncode(crypto.randomBytes(32));
// generate a challenge from the code verifier
var code_challenge = base64URLEncode(sha256(code_verifier));
```
For PKCE, you need both the code verifier and challenge values in later steps.
## Construct the authorization URL
<Alert severity="info">
See the [authorization endpoint reference documentation](oauth2-reference.md#get-v1authorize)
for complete information on how to construct the authorization URL.
</Alert>
To initiate the user authorization process, construct an
authorization URL with the required parameters:
- `client_id`: Your app's client ID obtained after [registering your app](oauth2-registration.md).
- `redirect_uri`: Your app's redirect URI, the re-entry point of your app.
- `scope`: The requested scopes that define the access permissions your app
needs in a space-separated list.
- `response_type`: Set it to `code` to indicate the authorization code flow.
**Required for PKCE only**
- `code_challenge`: The code challenge generated from a code verifier.
- `code_challenge_method`: Set this parameter value to `S256` to indicate that
the code challenge was transformed using the SHA-256 algorithm, the most
widely supported and secure code challenge method.
- `state`: An opaque, secure random value to maintain state
between the request and callback.
**Required for non-PKCE only**
- `client_secret`: Your app's client secret obtained after [registering your app](oauth2-registration.md). If you are using authentication with
PKCE, omit this parameter.
Your authorization request URL must be well formatted, like in the following
example:
```bash title="Example PKCE Authorization URL"
https://apis.roblox.com/oauth/v1/authorize?client_id=7290610391231237934964
&code_challenge=PLEKKVCjdD1V_07wOKlAm7P02NC-LZ_1hQfdu5XSXEI
&code_challenge_method=S256
&redirect_uri=https://example.com/redirect
&scope=openid%20profile
&response_type=code
&state=abc123
```
When users visit the URL, they are taken through the authorization flow. If
successful, Roblox redirects the user to the specified `redirect_uri`.
## Handle authorization callbacks
When an authorization flow is successful, your app receives a `GET` request from
the Roblox authorization server at the `redirect_uri` that you specified. In the
request, you receive `code` (authorization code) and `state`(if you provided a
value previously) parameters.
- The `code` parameter contains an authorization code that the app can
exchange for an access token from the authorization server. Most backend
server languages have standard ways to access query parameters as decoded
objects. You'll need to obtain the `code` parameter and use it to exchange
for access tokens.
- The `state` parameter is an opaque value that you initially provided in the
authorization request. You can use this parameter to maintain the state or
context of the authorization process.
For example, you might receive a `GET` request with the following URL if you
specified your redirect URI to be `https://example.com/redirect`.
```bash title="Example Redirect URL"
https://example.com/redirect?code=10c45PNuquKnFJ6pUcy5-fHkghEM6lSegm-7hj9mVEprub1dSDuStuKK_EAUXY7AHTD63xcnmvxSLthp-C8g3jzIGZVzuXSd20Y2dEYI9hx0LZmPg95ME4z2K03UheiZbroyXUjYyB3ReoMqobzDVPzyx6IS8kj2Uu-11Xq_0JiTYxtDatuqXRNIAmJT8gMJmbSyOLOP_vnDvbeMUiBsqCRrkTGVbWSwYSc8sTVVE-535kYdqQOgNjH1ffCoZLGl8YYxLnpb2CXJlRQPrcjkA&state=6789
```
If authorization fails, your app receives a `GET` request to the specified
redirect URL with the `error`, `error_description`, and `state` (if applicable)
parameters.
- The `error` parameter indicates the specific OAuth 2.0 error that occurred
during the authorization process.
- The `error_description` parameter provides additional details of the error.
- The `state` parameter helps your app maintain state in the case of a
failure.
## Exchange an authorization code for access tokens
When you have parsed the authorization `code`, exchange it for
tokens to access desired Roblox resources:
1. Request an access token and refresh token by sending a `POST` request to the
[token exchange endpoint](oauth2-reference.md#post-v1token). The
request must include the authorization code, client ID, and the code
verifier value (PKCE) or client secret (non-PKCE) in `x-www-form-urlencoded` format.
1. Parse the applicable tokens from the response received. The access token is
valid for 15 minutes. Store the refresh token securely, typically on the server side, so you can use it to obtain new tokens in the future.
```json title="Example Token Endpoint Response"
{
"access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IlBOeHhpb2JFNE8zbGhQUUlUZG9QQ3FCTE81amh3aXZFS1pHOWhfTGJNOWMiLCJ0eXAiOiJKV11234.eyJzdWIiOiIyMDY3MjQzOTU5IiwiYWlkIjoiM2Q2MWU3NDctM2ExNS00NTE4LWJiNDEtMWU3M2VhNDUyZWIwIiwic2NvcGUiOiJvcGVuaWQ6cmVhZCBwcm9maWxlOnJlYWQiLCJqdGkiOiJBVC5QbmFWVHpJU3k2YkI5TG5QYnZpTCIsIm5iZiI6MTY5MTYzOTY5OCwiZXhwIjoxNjkxNjQwNTk4LCJpYXQiOjE2OTE2Mzk2OTgsImlzcyI6Imh0dHBzOi8vYXBpcy5yb2Jsb3guY29tL29hdXRoLyIsImF1ZCI6IjcyOTA2MTAzOTc5ODc5MzQ5Nj1234.BjwMkC8Q5a_iP1Q5Th8FrS7ntioAollv_zW9mprF1ats9CD2axCvupZydVzYphzQ8TawunnYXp0Xe8k0t8ithg",
"refresh_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoidGpHd1BHaURDWkprZEZkREg1dFZ5emVzRWQyQ0o1NDgtUi1Ya1J1TTBBRSIsInR5cCI6IkpXVCJ9..nKYZvjvXH6msDG8Udluuuw.PwP-_HJIjrgYdY-gMR0Q3cabNwIbmItcMEQHx5r7qStVVa5l4CbrKwJvjY-w9xZ9VFb6P70WmXndNifnio5BPZmivW5QkJgv5_sxLoCwsqB1bmEkz2nFF4ANLzQLCQMvQwgXHPMfCK-lclpVEwnHk4kemrCFOvfuH4qJ1V0Q0j0WjsSU026M67zMaFrrhSKwQh-SzhmXejhKJOjhNfY9hAmeS-LsLLdszAq_JyN7fIvZl1fWDnER_CeDAbQDj5K5ECNOHAQ3RemQ2dADVlc07VEt2KpSqUlHlq3rcaIcNRHCue4GfbCc1lZwQsALbM1aSIzF68klXs1Cj_ZmXxOSOyHxwmbQCHwY7aa16f3VEJzCYa6m0m5U_oHy84iQzsC-_JvBaeFCachrLWmFY818S-nH5fCIORdYgc4s7Fj5HdULnnVwiKeQLKSaYsfneHtqwOc_ux2QYv6Cv6Xn04tkB2TEsuZ7dFwPI-Hw2O30vCzLTcZ-Fl08ER0J0hhq4ep7B641IOnPpMZ1m0gpJJRPbHX_ooqHol9zHZ0gcLKMdYy1wUgsmn_nK_THK3m0RmENXNtepyLw_tSd5vqqIWZ5NFglKSqVnbomEkxneEJRgoFhBGMZiR-3FXMaVryUjq-N.Q_t4NGxTUSMsLVEppkTu0Q6rwt2rKJfFGuvy3s12345",
"token_type": "Bearer",
"expires_in": 899,
"id_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IkNWWDU1Mi1zeWh4Y1VGdW5vNktScmtReFB1eW15YTRQVllodWdsd3hnNzgiLCJ0eXAiOiJKV11234.eyJzdWIiOiIyMDY3MjQzOTU5IiwibmFtZSI6ImxpbmtzZ29hdCIsIm5pY2tuYW1lIjoibGlua3Nnb2F0IiwicHJlZmVycmVkX3VzZXJuYW1lIjoibGlua3Nnb2F0IiwiY3JlYXRlZF9hdCI6MTYwNzM1NDIzMiwicHJvZmlsZSI6Imh0dHBzOi8vd3d3LnJvYmxveC5jb20vdXNlcnMvMjA2NzI0Mzk1OS9wcm9maWxlIiwibm9uY2UiOiIxMjM0NSIsImp0aSI6IklELnltd3ZjTUdpOVg4azkyNm9qd1I5IiwibmJmIjoxNjkxNjM5Njk4LCJleHAiOjE2OTE2NzU2OTgsImlhdCI6MTY5MTYzOTY5OCwiaXNzIjoiaHR0cHM6Ly9hcGlzLnJvYmxveC5jb20vb2F1dGgvIiwiYXVkIjoiNzI5MDYxMDM5Nzk4NzkzNDk2NCJ9.kZgCMJQGsariwCi8HqsUadUBMM8ZOmf_IPDoWyQY9gVX4Kx3PubDz-Q6MvZ9eU5spNFz0-PEH-G2WSvq2ljDyg",
"scope": "openid profile"
}
```
## Make a call to a resource method
Now that you have the required access token, you can use it to make
authenticated calls to resource methods. Include the access token in the header of all API requests to
authorize them.
For example, you can test if your app functions correctly by
going through the entire authorization flow and then making a `GET` request
to the
[user information endpoint](oauth2-reference.md#get-v1userinfo) with an access
token. Ensure you have the `openid` or both the `openid` and `profile`
scopes before calling this endpoint. If successful, the response from that
endpoint looks like this:
```json title="Example User Information Response"
{
"sub": "12345678",
"name": "Jane Doe",
"nickname": "robloxjanedoe",
"preferred_username": "robloxjanedoe",
"created_at": 1607354232,
"profile": "https://www.roblox.com/users/12345678/profile"
}
```

View file

@ -0,0 +1,167 @@
---
title: OAuth 2.0 overview
description: Introduces the 3rd-party app creation support with OAuth 2.0 authorization framework.
---
You can build or authorize apps that use Open Cloud APIs to access Roblox
resources. Open Cloud provides authentication for these apps using OAuth 2.0.
<dl>
<dt>**As an experience creator or group owner**</dt>
<dd>
You can securely use tools created by others to improve your creation
productivity. The OAuth 2.0 authorization layer allows you to grant permissions
to third-party apps to access your or your group's experiences without giving
them your credentials and personal information. You select the access
permissions of your specific Roblox resources, and Roblox handles the
authorization process for you with the OAuth 2.0 framework.
<Alert severity="info">
You must have a 13+ account to authorize OAuth 2.0 apps.
</Alert>
</dd>
<dt>**As an app developer**</dt>
<dd>
You can create apps for yourself and others in the Roblox community. OAuth 2.0
defines the roles involved in the authorization process, the protocol of how
roles interact with each other, and the authorization flows that you need to
follow to develop secure and compatible apps.
<Alert severity="info">
You must be [ID verified](../../production/publishing/account-verification.md#verify-through-government-id)
to register and publish OAuth 2.0 apps.
</Alert>
</dd>
</dl>
## Roles
The Open Cloud OAuth 2.0 protocol has the following roles. It's useful to
understand the specific roles before learning about how they interact with one
another in authorization flows.
- **Resource owner**: An entity capable of granting access to a protected
resource. For example, a creator who allows a third-party app to access
their Roblox resources through Open Cloud Web APIs.
- **Resource server**: A Roblox service that hosts protected resources and
responds to requests from a resource owner.
- **Client**: An app that accesses protected resources on behalf of the resource
owner (with the owner's authorization).
- **Authorization server**: The Roblox server that authenticates the identity of
the resource owner and issues access tokens to the client.
## Grant types
Authorization flows, or grant types, are the steps of actions that roles perform
during the authorization process. Roblox supports the OAuth 2.0 authorization
code flow and its Proof Key for Code Exchange (PKCE) extension, with different
implementation requirements for apps that are capable or incapable of storing
client secrets.
### Authorization code flow
Through the authorization code flow, a client exchanges an authorization code
for an access token and a refresh token to complete the authorization process in
the following steps:
1. The client sends an authorization request to the Roblox authorization server.
1. The authorization server verifies the identity of the resource owner.
1. The authorization server receives permissions for accessing specific Roblox
resources from the resource owner.
1. The authorization server redirects the resource owner back to the client with
an authorization code.
1. The client requests an access token using the authorization code at the token
endpoint.
1. The client receives a response from the token endpoint containing an access
token, an ID token, and a refresh token.
1. The client retrieves the permitted resources after getting the access token.
The following figure describes the interactions between roles in the
authorization code flow that you'll read in the following sections:
<img src="../../assets/open-cloud/protocol-flow.png" width="80%" />
### Authorization code flow with PKCE
The [PKCE extension](https://www.rfc-editor.org/rfc/rfc7636) of the
authorization code flow helps reduce risk of leaking the authorization code and
prevent cross-site request forgery (CSRF), an attack that tricks users into
submitting unintended web requests. This flow completes the authorization
process with the following steps:
1. The client generates a unique and cryptographically random key called a
_code verifier_ for every authorization request.
1. The client runs a SHA-256 hash algorithm on the code verifier to generate a
_code challenge_.
1. If the client:
- Is a [public client](oauth2-develop.md#public-clients),
instead of using the client secret, it passes the client ID and the code
challenge in the authorization request.
- Is a [confidential client](oauth2-develop.md#confidential-clients),
it adds the code challenge along with the client ID and secret in the
request.
1. The client sends an authorization request to the Roblox authorization server.
1. The authorization server verifies the identity of the resource owner.
1. The authorization server receives permissions for accessing specific Roblox
resources from the resource owner.
1. The authorization server redirects the resource owner back to the client with
an authorization code.
1. The client includes the authorization code and the original code verifier
in the token request to the [token endpoint](oauth2-reference.md#token-exchange).
1. The authorization server verifies the authorization code and the associated
code verifier.
1. The client receives a response from the token endpoint containing an access
token, an ID token, and a refresh token.
1. The client retrieves the permitted resources after getting the access token.
## OpenID Connect support
Roblox uses [OpenID Connect (OIDC)](https://openid.net/connect/) as an
identity layer on top of the OAuth 2.0 protocol for authentication to protect
sensitive account information. OIDC allows applications to verify the identity
of users and obtain their basic public profile information, such as user ID,
usernames, display names, and profile links.
<Alert severity="info">
When [adding permission scopes](oauth2-registration.md#register-an-app) to your app on
**Creator Dashboard**, make sure to select the `openid` identity scope for
receiving an ID token in the token response as part of the authentication
process.
</Alert>
## Registration and implementation
To implement a web or mobile app that uses authorization code flow, you need to:
1. [Register](oauth2-registration.md) your app with Roblox.
This lets you obtain a client ID and secret to register your app with Roblox
and make calls to your endpoints.
1. [Implement](oauth2-develop.md) the authorization code
flow. For a complete reference of the OAuth 2.0 endpoints that you need to
call, see the [Authentication](oauth2-reference.md) reference.
1. Go through the [review process](oauth2-registration.md#submit-for-review)
to get more user quota.

View file

@ -0,0 +1,427 @@
---
title: OAuth 2.0 authentication
description: Describes how to make authenticated calls to Open Cloud with API keys and OAuth 2.0
---
<Alert severity="warning">
OAuth 2.0 authentication is a beta feature that might be subject to change for
future releases. All Open Cloud endpoints also support
[API key authentication](../auth/api-keys.md).
</Alert>
<Alert severity="info">
For complete implementation guides and information on OAuth 2.0, including a
sample app, see the [OAuth 2.0 overview](../auth/oauth2-overview.md).
</Alert>
This document describes endpoints that you call to implement the OAuth 2.0
authorization code flow, as well as other endpoints useful for implementing
authentication in your apps.
```http title="Base URL"
https://apis.roblox.com/oauth
```
```http title="Endpoints"
GET v1/authorize
POST v1/token
POST v1/token/introspect
POST v1/token/resources
POST v1/token/revoke
GET v1/userinfo
GET .well-known/openid-configuration
```
## Authorization
### `GET` v1/authorize
Obtains authorization from the user to authenticate with their Roblox account.
Expects a valid authorization URL constructed with
the specified parameters. This endpoint supports PKCE authorization.
<h4>Query parameters</h4>
| Name | Description | Required | Example |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------- |
| client_id | The app's client ID. | yes | `816547628409595165403873012` |
| redirect_uri | The URL that users are redirected back to after the completing authorization flow. | yes | `https://www.roblox.com/example-redirect` |
| scope | The requested scopes, space delimited. Use the `openid` scope to receive an ID token. Use the `openid` and `profile` scope to obtain more user information. | yes | `openid profile` |
| response_type | The credentials the app wants returned. The default is the authorization code grant type. | yes | `none`, `code` |
| prompt | Specifies what authentication and consent pages are shown to users. Certain screens are required for third-party apps and can't be skipped. | no | `none`, `login`, `consent`, `select_account` |
| nonce | The cryptographic number that binds the token with the client. | no | `<random_value_1>` |
| state | An opaque value that prevents cross-site request forgery, a type of malicious attack. Passed back to the app after authorization. | no | `<app-provided-opaque-value>` |
| code_challenge | The resulting string of applying the `code_challenge_method` to the `code_verifier`. | no | Base64-URL-encoded string |
| code_challenge_method | The function that is applied to the `code_verifier`. | no | S256 |
<h4>Request</h4>
```plain title="Example Request of Directing to Authorization Flow"
https://apis.roblox.com/oauth/v1/authorize?client_id=816547628409595165403873012&redirect_uri=https://my-app.com/redirect&scope=openid&response_type=code&nonce=12345&state=6789
```
<h4>Response</h4>
After calling this endpoint, the user is redirected to the specified redirect
URL with the authorization code in a `code` query parameter.
The authorization code:
- Has a lifetime of one minute.
- Can only be redeemed once.
- Is invalid after one use.
## Token exchange
To obtain tokens to access APIs, exchange an **authorization code** for a set of
confidential tokens. All token endpoints support two types of client
authentication:
1. HTTP Basic Authentication Scheme with an authorization header:
`Authorization: Basic Base64 encoded(<client_id>:<client_secret>)`.
1. Client ID and secret in the request body as parameters.
The following list describes the various tokens you receive from this
endpoint.
- **Access token** - Represents the authorization from a creator or user for a
third-party app to access their protected Roblox resources. It's a string
denoting a specific scope, lifetime, and other access attributes. Once the
Roblox authorization server issues an access token to an app, the token:
- Is valid for 15 minutes.
- Can be used multiple times before it expires.
- Can be invalidated before it expires if an app user revokes the authorization.
- **Refresh token** - Refreshes an authorization session. An app can use
the refresh token to obtain a new set of tokens, which includes an access token,
a refresh token, and an ID token. A refresh token:
- Is valid for 90 days.
- Can only be used once before it expires to refresh tokens.
- Can be invalidated before it expires if an app user revokes the authorization.
- **ID token** - Provides proof that a user's identity has been authenticated. Its
content depends on the scopes requested and can contain basic user information,
including a user's Roblox display name and username. The ID token is only for
identity authentication purposes and doesn't provide access to any Roblox
resources.
### `POST` v1/token
Obtain a set of tokens with an authorization code.
<h4>Request</h4>
`(x-www-form-urlencoded)`
| Key | Value |
| ------------- | ---------------------------- |
| code | `<authorization code>` |
| code_verifier | `<pkce code verifier value>` |
| grant_type | authorization_code |
| client_id | `<client_id>` |
| client_secret | `<client_secret>` |
```bash title="Example Obtain Token Request"
curl --location --request POST 'https://apis.roblox.com/oauth/v1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=840974200211308101' \
--data-urlencode 'client_secret=RBX-CR9...St12L' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=yCnq4ofX1...XmGpdx'
```
<h4>Response</h4>
```json title="Example Obtain Token Response"
{
"access_token": "...",
"refresh_token": "...",
"token_type": "Bearer",
"expires_in": 899,
"scope": "universe-messaging-service:publish"
}
```
### `POST` v1/token
Obtain a set of tokens with a refresh token.
<h4>Request</h4>
`(x-www-form-urlencoded)`
| Key | Value |
| ------------- | ----------------- |
| grant_type | refresh_token |
| refresh_token | `<refresh_token>` |
| client_id | `<client_id>` |
| client_secret | `<client_secret>` |
```bash title="Example Refresh Token Request"
curl --location --request POST 'https://apis.roblox.com/oauth/v1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'refresh_token=Ujfstayclfdlbm...BGydlsnU' \
--data-urlencode 'client_id=840974200211308101' \
--data-urlencode 'client_secret=RBX-CR9...St12L'
```
<h4>Response</h4>
```json title="Example Refresh Token Request"
{
"access_token": "...",
"refresh_token": "...",
"token_type": "Bearer",
"expires_in": 899,
"scope": "universe-messaging-service:publish"
}
```
### `POST` v1/token/introspect
Receive information about a token. Verifies whether the token is presently valid
and hasn't expired yet. Useful for stateless validation. Use only if the API
you're accessing doesn't require a resource, such as Assets API, or if you just
want to see specific claims of the token.
<Alert severity="info"> Even if the user has revoked the authorization linked to
the access token, the endpoint still shows the access token as `valid: true`
because it checks whether the token is active based on its lifetime (typically
15 minutes for access tokens). </Alert>
<h4>Request</h4>
`(x-www-form-urlencoded)`
| Key | Value |
| ------------- | --------------------------------------------------- |
| token | `<access_token>`, `<refresh_token>` or `<id_token>` |
| client_id | `<client_id>` |
| client_secret | `<client_secret>` |
```bash title="Example Introspect Token Request"
curl --location --request POST 'https://apis.roblox.com/oauth/v1/token/introspect' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'token=eyjlflabtfl...4gxqYBG' \
--data-urlencode 'client_id=840974200211308101' \
--data-urlencode 'client_secret=RBX-CR9...St12L'
```
<h4>Response</h4>
```json title="Example Introspect Token Response"
{
"active": true,
"jti": "RT.2GcjvTduKzk6QY9tjTfm",
"iss": "https://apis.roblox.com/oauth/",
"token_type": "Bearer",
"client_id": "840974200211308101",
"aud": "4239311013248676173",
"sub": "1516563360",
"scope": "universe-messaging-service:publish",
"exp": 1676394509,
"iat": 1660842510
}
```
### `POST` v1/token/resources
Check whether a token can access a specific resource by obtaining the list of
user resources that the user gave permission for. This is useful for stateful
validation.
<h4>Request</h4>
`(x-www-form-urlencoded)`
| Key | Value |
| ------------- | ----------------- |
| token | `<access_token>` |
| client_id | `<client_id>` |
| client_secret | `<client_secret>` |
```bash title="Example Obtain Token Resources Request"
curl --location --request POST https://apis.roblox.com/oauth/v1/token/resources' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'token=eyjlflabtfl...4gxqYBG' \
--data-urlencode 'client_id=840974200211308101' \
--data-urlencode 'client_secret=RBX-CR9...St12L'
```
<h4>Response</h4>
The value `U` in `ids` indicates that a scope has granted access to a resource owned by the authorizing `owner`.
```json title="Example Obtain Token Resources Response"
{
"resource_infos": [
{
"owner": {
"id": "1516563360",
"type": "User"
},
"resources": {
"universe": {
"ids": ["3828411582"]
},
"creator": {
"ids": ["U"]
}
}
}
]
}
```
### `POST` v1/token/revoke
Revoke an authorization session using the provided refresh token.
<h4>Request</h4>
`(x-www-form-urlencoded)`
| Key | Value |
| ------------- | ----------------- |
| token | `<refresh_token>` |
| client_id | `<client_id>` |
| client_secret | `<client_secret>` |
```bash title="Example Revoke Token Request"
curl --location --request POST https://apis.roblox.com/oauth/v1/token/revoke' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'token=Ujfstayclfdlbm...BGydlsnU' \
--data-urlencode 'client_id=840974200211308101' \
--data-urlencode 'client_secret=RBX-CR9...St12L'
```
<h4>Response</h4>
`200 OK` with an empty response
## User Information
### `GET` /v1/userinfo
Gets the Roblox user ID and other user metadata.
<h4>Request</h4>
**Authorization header**: `Authorization: Bearer <access_token>`
```bash title="Example Get User Info Request"
curl --location --request GET 'https://apis.roblox.com/oauth/v1/userinfo' \
--header 'Authorization: Bearer eyjlflabtfl...4gxqYBG'
```
<h4>Response</h4>
You can use the `sub` value to uniquely identify the user. Users can change
their Roblox username and display name, so don't use them as unique identifiers to refer to users on your app.
| Claim | Description |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| sub | Roblox user ID. |
| name | Roblox display name. |
| nickname | Roblox display name. |
| preferred_username | Roblox username. |
| created_at | Creation time of the Roblox account as a Unix timestamp. |
| profile | Roblox account profile URL. |
| picture | Roblox avatar headshot image. Can be null if the avatar headshot image hasn't yet been generated or has been moderated. |
```json title="Example User with Profile Scope"
{
"sub": "1516563360",
"name": "exampleuser",
"nickname": "exampleuser",
"preferred_username": "exampleuser",
"created_at": 1584682495,
"profile": "https://www.roblox.com/users/1516563360/profile",
"picture": "https://tr.rbxcdn.com/03dc2a9abe7b1aacaaf93ea46d5c0646/150/150/AvatarHeadshot/Png"
}
```
```json title="Example User without Profile Scope"
{
"sub": "1516563360"
}
```
## Discovery
The OpenID Connect (OIDC) Discovery Document is a JSON document that
contains metadata about the Open Cloud configuration details, including a list
of identity-related scopes and claims that are supported. You can use it to
dynamically discover information about Open Cloud OAuth 2.0 endpoints and
configuration, such as the authorization endpoint, token endpoint, and public
key set.
After retrieving and fetching the Discovery Document from the Discovery document
URI, you can either manually inspect fields in the response to verify the
information, or you can create your own custom library mapping to fields in the
response schema to automate your workflow.
### `GET` .well-known/openid-configuration
<h4>Response</h4>
All Discovery Document responses follow the same schema as the following example response.
<Alert severity="warning">
Not all of the following scopes and claims are available to third-party app creators, as some can only be used by official Roblox apps.
</Alert>
```json title="Example Discovery Document Response"
{
"issuer": "https://apis.roblox.com/oauth/",
"authorization_endpoint": "https://apis.roblox.com/oauth/v1/authorize",
"token_endpoint": "https://apis.roblox.com/oauth/v1/token",
"introspection_endpoint": "https://apis.roblox.com/oauth/v1/token/introspect",
"revocation_endpoint": "https://apis.roblox.com/oauth/v1/token/revoke",
"resources_endpoint": "https://apis.roblox.com/oauth/v1/token/resources",
"userinfo_endpoint": "https://apis.roblox.com/oauth/v1/userinfo",
"jwks_uri": "https://apis.roblox.com/oauth/v1/certs",
"registration_endpoint": "https://create.roblox.com/dashboard/credentials",
"service_documentation": "https://create.roblox.com/docs/reference/cloud",
"scopes_supported": [
"openid",
"profile",
"email",
"verification",
"credentials",
"age",
"premium",
"roles"
],
"response_types_supported": ["none", "code"],
"subject_types_supported": ["public"],
"id_token_signing_alg_values_supported": ["ES256"],
"claims_supported": [
"sub",
"type",
"iss",
"aud",
"exp",
"iat",
"nonce",
"name",
"nickname",
"preferred_username",
"created_at",
"profile",
"email",
"email_verified",
"verified",
"age_bracket",
"premium",
"roles",
"internal_user"
],
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"client_secret_basic"
]
}
```

View file

@ -0,0 +1,140 @@
---
title: OAuth 2.0 app registration
description: Explains how to register an app and how the review workflow works.
---
Registering your OAuth 2.0 app allows it to access Roblox resources. After
registration, Roblox assigns the app a unique client ID and secret that you can
use to obtain authorization from users to access their Roblox information and
resources.
<Alert severity="info">
You can only register apps for individual accounts or groups that you own.
</Alert>
## Register your app
To register an app:
1. In the [Creator Dashboard](https://create.roblox.com/dashboard/creations), go to the [OAuth 2.0 Apps](https://create.roblox.com/dashboard/credentials?activeTab=OAuthTab) page.
1. Click the **Create App** button.
1. Enter a valid and globally unique **Application Name**.
1. Read and agree to the **Roblox Terms of Service** and click **Create**.
1. Copy and store the **Client ID** and **Secret** in a secure place. After
closing the page, you no longer have access to the secret and can only
generate a new one. After you finish registering an app, you can still access
and edit the app's other properties.
1. Click **Continue to Edit** to configure your app, which is described in the
following sections.
## Configure general information
Once you've [registered](#register-your-app) your app, you should configure its general information, including:
- A description, which is visible to everyone in the Roblox community.
- A thumbnail image for your app. The recommended file size is at least 150x150
pixels.
- An **Entry Link** as the entry point of your app, such as the app's website
homepage.
- A **Privacy Terms URL** and a **Terms of Service URL** for end-users to read
before authorizing your app. Each URL must be HTTPS and no more than 256
characters.
<Alert severity="info">
You can skip this section during app development and testing, but you must
complete it during the review process to publish your app to users.
</Alert>
## Add permissions
To ensure proper access control and security within your app, you must add
**Permission Scopes**. There are two types of permission scopes available:
- **Identity scopes** for authentication, such as `openid` for user IDs and
`profile` for the full profiles. If you select the `profile` scope, you must
also select `openid`.
- **API-specific permission scopes**, such as `asset:read` for the read
permission of assets. Select only the minimum number of scopes that you need
for your app.
## Add redirect URLs
**Redirect URLs** are the reentry points of your app that users are redirected
to when they finish authorizing your app. Ensure your
redirect URLs meet the following requirements:
- All redirect URLs must be in one of the following forms:
- Plain HTTPS, for example: `https://www.example.com`.
- Paths on localhost with HTTP or HTTPS (self-signed certificate) for local
debugging purposes, for example:
- `http://localhost:80`
- `https://localhost:80`
- Custom schemes for specific applications or purposes, for example:
- `my-app-scheme:/`
- `my-app-scheme://foo/bar/...`
- `my-app://action?param1=value1&param2=value2`
- The maximum length of a redirect URL is 256 characters.
- You can add up to 10 redirect URLs. With multiple redirect URLs, you can have
test environments and allow users to migrate between two sites without
downtime.
<Alert severity="info">
You can skip this step during app registration and add the redirect URLs later
when you have a testable version of your app.
</Alert>
## Submit for review
To minimize the chances of malicious apps harming the community, registering an
app doesn't make it broadly accessible. Instead, it remains in **private mode**
with a limit of 10 unique users. This mode is helpful for testing and
debugging within your team.
If you want to extend the user base for your app, you need to publish it in
public mode by submitting it for review:
1. Go to the [OAuth 2.0 apps](https://create.roblox.com/dashboard/credentials?activeTab=OAuthTab) page.
1. Click the **Edit and Publish** button for the app that you want to publish.
1. Fill in all the required information and click the **Review and Publish**
button. A message with limits on your app permissions during the pending
review period appears.
1. Click **Submit for Review**.
While your app review is pending, you can't edit or submit another request until
the current review request is approved or rejected. Your app remains in
private mode during the review. When your app is approved, it transitions to
public mode, and you can't revert it back to private mode.
Regardless of whether your app is approved or rejected, you receive an email
notification of the result when the review is completed.
## Edit and delete your app
You can edit or delete your app with the following steps if it's not under
review:
1. Go to the [OAuth 2.0 apps](https://create.roblox.com/dashboard/credentials?activeTab=OAuthTab) page.
1. Click **Edit** or **Delete** for the desired app.
- If you chose to edit an app, follow the same steps and requirements of
[registration](#register-your-app).
- If you chose to delete an app, click **Yes, Delete** to confirm deletion.
After you delete an app, you can't recover it.
Modifying your app's general information or redirect URLs does not require users
to reauthorize the app. However, if you add or modify permission scopes, you
must obtain authorization for the new permissions from your users and acquire a
new set of tokens. If you don't obtain authorization for the new scopes, your
app can continue using the existing tokens, but is limited to the previous
scopes.
For apps in private mode, the system automatically updates your edits with your
users. For apps in public mode, you must
[submit the app for review](#submit-for-review) again to reflect these changes.
Otherwise, the system saves the unpublished changes for you without releasing it
to the community.
<Alert severity ='info'> You can clone a copy of your public app and keep it in
private mode for iterative testing and debugging. This allows for a controlled
environment where you can safely make changes and resolve any issues before
submitting the app for review.</Alert>

View file

@ -0,0 +1,79 @@
---
title: OAuth 2.0 sample app
description: Provides a working OAuth 2.0 sample application.
---
Roblox provides a Node.js sample app that shows how to use OAuth 2.0 to let users log in to their Roblox accounts and broadcast messages across their experiences. This app uses the [authorization code flow _without_ PKCE](oauth2-overview.md#grant-types) and is thus only suitable for confidential clients, such as private servers.
<a href="../../assets/open-cloud/open-cloud-nodejs-sample-oauth2-main.zip">
<Button variant="contained">Get the Code</Button>
</a>
<br />
After downloading the `.zip` file, extract it to its own folder.
## Register the app
The first step to setting up the app is to [register it on the Roblox website](oauth2-registration.md) and copy the client ID and secret somewhere safe. Then follow the standard registration steps with these settings:
1. Under **Permissions**, add the `openid`, `profile`, and `universe-messaging-service:publish` scopes.
1. Under **Redirect URLs**, add the `http://localhost:3000/oauth/callback` redirect. If you want to use a non-default port for your app, specify it here.
## Set environment variables
Rather than storing them in code (not recommended), the app uses environment variables for your client ID and secret. The process for adding environment variables differs by operating system.
On Windows, run the following PowerShell commands:
```powershell
$env:ROBLOX_CLIENT_ID='your_client_id_here'
$env:ROBLOX_CLIENT_SECRET='your_client_secret_here'
$env:ROBLOX_PORT=3000 # Optional. Default is 3000.
```
On Mac and most Linux distributions, run these commands at the terminal:
```bash
export ROBLOX_CLIENT_ID=your_client_id_here
export ROBLOX_CLIENT_SECRET=your_client_secret_here
export ROBLOX_PORT=3000 # Optional. Default is 3000.
```
If you specified a non-default port in the redirect URL when registering your app, be sure to add the `ROBLOX_PORT` variable.
<Alert severity="info">
These commands only set environment variables for the duration of your terminal session. If you want to load these variables every time you open a new terminal window, add the commands to your shell configuration file, such as `.zshrc` or `.bashrc`. Many hosting services have features to help you add environment variables to your servers.
</Alert>
## Install dependencies
The app has a handful of dependencies, visible in `package.json`. To install them, run:
```bash
npm ci
```
## Run the app
To start the app, run:
```bash
npm start
```
Then navigate to `http://localhost:3000` (or your non-default port) in a web browser.
The app immediately redirects you to the Roblox login screen, at which point you can log in, verify the permissions that the app is requesting, and click **Confirm and Give Access**.
Roblox then redirects you back to `localhost`, where you can see that the app now displays some minimal user information, a link back to your profile on Roblox, and fields that you can use to broadcast messages across your experiences.
### About the app
In broad strokes, `index.js` performs the following operations:
1. Starts a new web server using `express`.
1. Retrieves the Roblox OpenID Connect (OIDC) configuration, which includes endpoints for authorization, user information, etc. For more information about these endpoints, see [OAuth 2.0 authentication](oauth2-reference.md).
1. Creates a new Open ID client using `openid-client` and your stored credentials. This client dramatically simplifies the process of properly forming and sending HTTP requests to the OAuth 2.0 endpoints.
1. Defines the routes for the app, including redirects for the login and logout flows and the OAuth 2.0 callback.
1. After a successful login, stores the various tokens as cookies, along with some minimal user information that it displays as HTML with help from `getHomeHtml.js`.