How do I append a secret to a URL so I can send a well-formed HTTP request?

I do have a working system for this, but I do not believe it is as secure as Roblox’s secret system.

I am using Google’s AI API in my Roblox game, and it requires me to put the API key inside the URL. If I use the API key as plaintext in the URL, it works. However, if I use Roblox’s secret API to retrieve the key and append it to the URL using secret:AddPrefix(URL), I get a 400 Bad Request error. I believe this is because it is interpreting the API key as something like Secret(Key) instead of the actual key.

The workaround I do is to store the secret in a TextLabel inside ServerStorage. On startup, my script fetches the secret in the TextLabel. After that, it immediately deletes the TextLabel.

The reason I am especially worried is that the AI generates arbitrary code and it is run server-side.

If your script that sends the request is in ServerScriptService then clients can’t see it, so malicious players can’t see your token even if it is in the script.

They send a prompt to the AI, and the AI makes code. The code is run server-side. Someone could try something like “get the value of a variable named “key” from this script and display it on a part.”

The client can’t see scripts in ServerScriptService because the server simply doesn’t send the contents of ServerScriptService to clients.

Uhh as he said client cant see the server scripts and its not possible to get the script in anyway possible

If the client somehow has access to ServerScriptService there isn’t really anything you can do against them because they probably control the entire server and can get the key from memory.

1 Like

Just make sure your script is inside ServerScriptService and everything should be fine. :+1:

The player does kind of have access to ServerScriptService, they give a prompt to an AI, and the AI generates code that is run on the server. The code is wrapped in a coroutine.wrap function however.

Can you give the script ? So we can understand what you mean easier

Letting clients run code on the server is a little dangerous.

This is a function in a ModuleScript:

function module.AI(api_key, prompt)
	local url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-exp-1206:generateContent?key=" .. api_key
	local t = {} -- I ommited the table contents for brevity
	local json = HttpService:JSONEncode(t)
	local status, err = pcall(function()
		local response = HttpService:PostAsync(url, json)
		local code = tostring([[ This part just gets the code from the response ]])
		return string.sub(code, 7, -5)
	end)
	return status, err
end

And this is the ServerScript that actually executes the code:

local AI = require(game.ReplicatedStorage.AI).AI
local HttpService = game.HttpService
local Key = game.ServerStorage.AiApiKey.Text

game.ServerStorage.AiApiKey.Text = ""
game.ServerStorage.AiApiKey:Destroy()

function Callback(player, prompt)
	local status, err = AI(Key, prompt)
	local code = err
	if status then
		local func = loadstring(code)
		local status, err = pcall(coroutine.wrap, func)
		if not status then
			warn("Coroutine wrap failed:", err)
			return status, err
		end
		status, err = pcall(err)
		if not status then
			warn("AI Generated code errored:", err)
			return status, err
		end
	end
	return status, code
end

game.ReplicatedStorage.AITrigger.OnServerInvoke = Callback

Edit: @efsane14010 Sorry I replied to the wrong person

aahh ok I see but where is the place that they can access the api key from the client?

The AI could generate code that accesses things visible to the server, and display the data as text on a part.

But you are not passing your script to the Api. Api is just getting the “prompt” variable and it doesnt make the script readable with ai

What if the AI generates something like this? (Lua Pseudocode):

local code = GetScript().Source
local key = code.variables.key.value
local p = new part
local s = new SurfaceGui
s.Parent = p
s:AddText(key)

Yes the AI does not access it directly, but it could make code that accesses it.

what is GetScript().Source refferring to ?and why is the key in a Value Instance?

I said it was pseudocode. This is not exactly what is happening, just me trying to explain.