Secrets Store General Availability

Are you running an instance in a local studio instance or in production? Secrets are only available for use in production and Team Create environments. If this is the case I recommend publishing your test place and trying it out on a live server. I also made a short script to specifically test out the problem you are having for use on a live server. Simply view the developer console in game to view its output.

local HttpService = game:GetService("HttpService")

local testKey = nil

local success, errorMessage = pcall(
	function()
		testKey = HttpService:GetSecret(SecretId)
	end
)

if success then
	print(testKey) --this will print Secret(SecretId) if successful--
else
	warn(errorMessage)
end

se

1 Like

Since they aren’t printable by design, is it meant for API keys only?

When this was announced at RDC23, I was thinking this could be a good way to store classic Twitter Codes if for whatever reason putting the plain text in server scripts would not be enough.

1 Like

I believe this is solely usable for keys used in HttpService requests. It would be really cool to have a way to store ANY codes/keys/etc. without having them be plaintext in scripts or hosted off-platform using some API.
Real quick: I just did a simple boolean comparison test to see if you could compare the value of a Secret with plaintext, even though it wasn’t part of the described features. Expectedly, it didn’t work as the value of the Secret will always be Secret(SecretID) until its decrypted by Roblox’s server’s for use in a HttpService request.

3 Likes

This was a much needed update and I’m so happy we finally have it.

1 Like

It doesn’t seem to be getting the secret from the secret store?


This returns an error that says that the key couldnt be found.

I did put a secret in the secret store under that name though?

2 Likes

Do you run “Team Test” or just “Local Test”?
At the moment, only Team Test and production can fetch secrets from the Secret Store. This limitation is done to protect your secrets from being downloaded to your local computer. We are working on supporting locally defined secrets (my thinking, when we run the Local Test in Studio, we should just read secrets from some local file on your computer).

4 Likes

Ah, I always use local test. I’ll make sure to use team test instead.

1 Like

This is a great feature! Is this heading torwards being able to send requests to roblox to get stuff like how many players are in a place/experience, or seeing how many visits a place/experience has?

2 Likes

This has been fixed. See release notes: Release Notes for 619 | Documentation - Roblox Creator Hub

Fixes casing of Class.Secret:AddPrefix() and Class.Secret:AddSuffix(); you can now use them in UpperCamelCase as intended.

2 Likes

I’m getting this error constantly during live servers, not sure what I’m doing as the key parameter in my GetSecret request is perfectly aligned with what I’ve set on the creator dashboard.



1 Like

Just done a little debugging, turns out that calling GetSecret as soon as the server initialises causes the Can't find secret with given key error.

Just added in a small yield before the request is sent and it seems to be working fine now.

1 Like

I experienced the same issue with GetSecret returning that the SecretKey did not exist, even though the key existed in the experience. I can confirm that yielding (Thanks for the suggestion) fixes the issue.

This is a bug and should be addressed - GetSecret is run synchronously, I expect it to yield until the secrets are retrieved from the secrets store and then check to see if the key exists; not (As a dev) needing to wait an arbitrary amount of time for new servers to spin up and hoping that the keys are retrieved in time.

1 Like

Current behaviour is a compromise: game server startup is not blocked by Secrets (primarily, because most servers do not require secrets available at startup). However it is expected that Secrets are fetched in parallel with the rest of game server startup, and by the time it starts, Secrets are available. That said, I also consider “Secret not exist” as a problem - either a bug, or rare unfortunate event that should be happening super-rarely. Based on your feedback, this isn’t rare at all, and therefore must be looked into. One approach that I think is useful would be exposing RefreshSecrets functionality, that is synchronous, and waits until Secrets are received.

3 Likes

Thanks for looking into this! For additional context, I was using the Knit framework by sleitnick, and the GetSecret call was in the KnitInit portion of a server-side service. Putting the GetSecret call under the KnitStart portion of the code fixed it (a few hundred milliseconds after a new server starts up).

1 Like

Thank you for noticing! It could’ve been caused by the oversight on our side, which, I believe, has been now addresses. Apologies for the inconvenience - Secrets, indeed, are expected to be readily available straight away after launching the server.

2 Likes

Hi,

There’s a paradox with requiring that Studio be in Team Test in order to use Secrets, and this paradox defeats a lot purpose that Secrets have. It makes it impossible to do any debugging/development of a system without analogously “pushing to main” every time you use it.

tl;dr - I think RunService needs something like IsTeamTest(), but here’s how this is problematic:

  1. I have a webserver that should only do work if an incoming request has passed an accepted Secret in it’s headers. Creating an inclusion list for all of Roblox’s IP ranges simply isn’t going to cut it.

  2. This webserver should not touch sensitive systems (Open Cloud DataStores, MemoryStores, MessagingService) if this secret denotes that it came from a Studio-based environment so that we may debug the game, systems, et cetera.

  3. The Team Test environment does not consider itself “in Studio”, so developers have no way of safe-guarding external systems from a Team Test session.

The alternative is to just simply pass a hard-coded studio header, but now my webserver is vulnerable to doing unauthenticated work because the secret is stored in plaintext to anyone with access to the code, and also isn’t secret anymore.

The need to know if we’re in a Team Test session is valuable, so that we can use a Studio/Team Test specific Secret.

2 Likes

The best solution to this problem is querying and whitelisting the server and port that your Team Test is running on. Of course to be completely secure you’d need to prevent IP spoofing, but that is probably overkill for your project.
Check out the GameJoin Api v1, specifically the portions regarding team create sessions. You are going to need a CSRF token to access these endpoints, which you can get by sending a request authenticated with your .ROBLOSECURITY code to the logout endpoint. This request will return using the IP and port your Team Create session is running on so you can just whitelist that instead of everything.

I know this solution isn’t ideal, but the only other way to seemingly solve this issue would be for Roblox to add specific TLS/SSL certificates to requests that have been sent via local studio, Team Create, and live game instances to differentiate. Maybe they have something in the works like that, but that just seems like a big headache to me lol.

2 Likes

No. They just need to add an IsTeamCrate() in RunService so that we can differentiate. This should have nothing to do with certificates, whitelisting IPs, or pinging any specific endpoint.

1 Like

I understand what you are saying, and I provided a working solution for your problem.

That being said an IsTeamTest() function for RunService simply wouldn’t be secure to send requests to your webserver. You would just be able to run the body inside of the conditional without that check. This is where certificates come in. If your request is signed showing that it is from a TeamCreate session you would be able to properly handle and serve that request with what you want, rather than what you would send for a request via a live game instance.

I think an IsTeamTest() function could work quite well for adding tools and functionality for testers directly in app, but this would not be a secure way to verify that a specific request is coming from a TeamTest session on your external server.
I’m happy to provide any clarification you may need and please don’t take this criticism too harshly.

If you really need a feature like this you could simply check using IsStudio() and checking the playercount

Hang tight, we’re working on a solution that will be local to the Studio instance, and are used for locally running games!

5 Likes