Using OpenCloud API
Secrets can be managed programmatically, via an OpenCloud API. You need Secrets Store API System enabled for your API Key. Alternatively, you may create an OAuth App with universe.secret:read
and universe.secret:write permissions
. Since secrets are associated with Experiences, you need to know the universeID
.
List Experience secrets
Lists all secrets defined for this experience. Secret content is not returned. Requires read
permission.
Example:
curl -H 'Content-Type: application/json'\
'https://apis.roblox.com/cloud/v2/universes/<universeID>/secrets'\
-H 'x-api-key: <API Key>'
Sample Response:
{"secrets":
[{
"id":"gcp",
"domain":"*.google.com",
"created":"2023-11-07T18:15:01.809Z",
"updated":"2023-11-07T18:15:01.809Z"
}],
"nextPageCursor":"n2o2djcA",
"previousPageCursor":"p2o2djcA"
}
Get Experience public key
Retrieves the public key for your experience. You need it to encrypt the secret content before sending it to Roblox. The API requires read
permission.
Example:
curl -H 'Content-Type: application/json'\
'https://apis.roblox.com/cloud/v2/universes/<universeID>/secrets/public-key'\
-H 'x-api-key: <API Key>'
Sample Response:
{
"id":"public-key",
"secret":"Zgj4+V7vSaEZ06rXazKJUIcUnVa95tUNiwXAif/vdHo=",
"key_id":"1200590785272263122"
}
Create a new Secret
Creates a new Secret (fails if a secret with this name already exists), which requires write permission. The secret must be encrypted before sending it to Roblox. Encrypt your secret using LibSodium sealed box. The example below uses Python and PyNaCl to create a sealed box (run pip install pynacl
to install it locally).
Create Python script with this content (use your own public key and secret content there):
from base64 import b64encode
from nacl import encoding, public
public_key = "Zgj4+V7vSaEZ06rXazKJUIcUnVa95tUNiwXAif/vdHo="
secret_content = "my_api_key_content"
public_key = public.PublicKey(public_key.encode("utf-8"), encoding.Base64Encoder())
sealed_box = public.SealedBox(public_key)
encrypted = sealed_box.encrypt(secret_content.encode("utf-8"))
print(b64encode(encrypted).decode("utf-8"))
Run the script python3 seal_box.py
. Script output is your encrypted secret, e.g. Bgy1ky7Se3xSquRc1b/T1C1FIxXbEDppMRA2trpJy1luT7NY6UQDT+rk6qnnGq09lQl9EQQU5xKsWCk=
Example creating a new secret and sending encrypted content:
curl -H 'Content-Type: application/json'\ 'https://apis.roblox.com/cloud/v2/universes/<universeID>/secrets'\
-d '{"id":"gcp","domain":"*.google.com",
"secret":"Bgy1ky7Se3xSquRc1b/T1C1FIxXbEDppMRA2trpJy1luT7NY6UQDT+rk6qnnGq09lQl9EQQU5xKsWCk=", "key_id":"1200590785272263122"}'\
-H 'x-api-key: <API Key>'
Sample Response:
{
"id":"gcp",
"created":"2023-11-07T18:15:01.809Z",
"updated":"2023-11-07T18:15:01.809Z"
}
Update existing Secret
Use the same encryption script to get the sealed box. Requires write
permission.
Example:
curl -X PATCH -H 'Content-Type: application/json'\
'https://apis.roblox.com/cloud/v2/universes/<universeID>/secrets/gcp'\
-d '{"secret":"rlkpVPeg+Fyh+eSTGLTySlQBV8MszuOcvq56SGWHLU39avqLw24bDmkhQHms+6NOlnJ6kiPbCG1KE70=", "key_id":"1200590785272263122"}'\
-H 'x-api-key: <API Key>'
Sample Response:
{"updated":"2023-11-07T18:23:53.334Z"}
Delete existing Secret
Requires write
permission.
Example:
curl -X DELETE -H 'Content-Type: application/json'\
'https://apis.roblox.com/cloud/v2/universes/<universeID>/secrets/gcp'\
-H 'x-api-key: <API Key>'
Response:
HTTP status code 200 when successful.