We have an automated deployment process where we specify both secrets and environment variables programatically through the flyctl CLI whenever we deploy a job.
It’s my experience that updating secrets is not atomic with app updates (updating secrets triggers a deploy with new secrets but old app version), so it requires some care to iron out certain edge cases.
My question is, since we’re not relying on fly to store secrets for us (in our use cause, we will always set them on fly deploy alonside other environment variables), what security advantage (if any) is there over just specifying our secrets as regular environment variables?
Secrets are stored in an encrypted vault. When you set a secret through flyctl, it sends the secret value through our API which writes to the vault for your specific application. The API servers can only encrypt, they cannot decrypt secret values. Secret values are never logged.
When we launch a VM for your application, we issue the host it runs on a temporary auth token it can use to decrypt your app secrets. The Fly.io agent on the host uses this token to decrypt your app secrets and inject them into your VM as environment variables at boot time. When you de-provision your VM, the host environment no longer has access to your app secrets.
flyctl and our API servers are designed to prevent user secrets from being extracted. However, secrets are available to your application code as environment variables. People with deploy access can deploy code that reads secret values and prints them to logs, or writes them to unencrypted data stores.
Essentially, secrets are guaranteed to be encrypted, and have higher security than standard environment variables.