Secrets
Scaffoldly provides a way to manage sensitive information, such as API keys and database credentials, without exposing them in your codebase. Instead of hardcoding secrets in your application, you can use the Secrets feature to securely store and access them.
Since Scaffoldly integrates with GitHub Actions, you can use GitHub Secrets to store your sensitive data, and transparently inject them into your application at runtime.
Setting Up Secrets
Secrets are only synchronized to the runtime environment during the deployment process. If a secret is updated in GitHub, you must re-deploy your application to synchronize the changes.
You may trigger a deployment by pushing changes to your repository, or by manually triggering the GitHub Actions workflow.
⚠️ Running npx scaffoldly deploy
locally will not synchronize secrets from GitHub
- Go to your GitHub repository.
- Navigate to
Settings
>Secrets and variables
>Actions
. - Click on
New repository secret
to add a new secret. - Enter the name of your secret (e.g.,
MY_SECRET
) and its value. - Click
Add secret
to save it.
Pushing and Accessing Secrets
You can access the secrets in your GitHub Actions workflow using the secrets
context. Here’s an example of how to use it in your .github/workflows/scaffoldly.yml
file:
- GitHub Action
- Scaffoldly Configuration
- Your Application
name: Scaffoldly Deploy
jobs:
deploy:
# ... snip ...
- name: Deploy
uses: scaffoldly/scaffoldly@v1
with:
secrets: ${{ toJSON(secrets) }} # inject repository secrets
Explanation:
- The
secrets
context allows you to access all the secrets you have defined in your GitHub repository. - The
toJSON(secrets)
function converts the secrets into a JSON format that can be used by the Scaffoldly action. - The
Deploy
step uses thescaffoldly
copies the secrets into the deployment environment.
See: GitHub Action Reference for more information.
{
"name": "my-app",
// other package.json configuration....
"scaffoldly": {
"secrets": ["MY_SECRET"]
// other scaffoldly configuration...
}
}
Explanation:
- The
secrets
array specifies which secrets from your GitHub repository should be uploaded to the Secret Store during deployment. - The names must match the names of the secrets defined in GitHub.
See: Configuration Reference for more information.
const mySecret = process.env.MY_SECRET;
Explanation:
- The
secrets
array specifies which secrets from your GitHub repository should be uploaded to the Secret Store during deployment. - The secrets will be injected as environment variables at runtime, allowing you to access them in your application code.
See: Environment Variables for more information.
A Real-World Example
Let's build out secrets and environment variables for a real-world application that connects to a PostgreSQL database and uses SendGrid for sending emails.
Your application needs:
- A database URL
- Developers use
postgresql://root:testing@localhost:5432/mydb
locally - A different Database URL for use in production
- Developers use
- An API key for SendGrid
- Developers get this value from 1Password for their local environment
- A different API key for use in production
Set up your project, and GitHub Actions in the following way:
- Local Environment
- .env File
- Repository Secrets
- Scaffoldly Config
- GitHub Action
- Your Application
export SENDGRID_API_KEY_DEV="some_shared_sendgrid_api_key" # copied from 1Password
Explanation:
- Since
SENDGRID_API_KEY
is sensitive, it should not be stored in your codebase. dotenv
will pull it into.env
at runtime.
DATABASE_URL="postgres://root:testing@localhost:5432/mydb"
SENDGRID_API_KEY="${SENDGRID_API_KEY_DEV}" # injected using dotenv
Explanation:
- The
.env
file contains the "default" local environment variables for local development. dotenv
will pull in theSENDGRID_API_KEY
from your profile.
-
DATABASE_URL
postgres://some-username:some-password@mydbinstance.abcdefghij.us-east-1.rds.amazonaws.com:5432/some-database
-
SENDGRID_API_KEY
:a_different_sendgrid_api_key`
Explanation:
- We're using GitHub as a secret store for sensitive information.
- Scaffoldly will automatically upload these secrets into the Secret Store during deployment.
- Scaffoldly will inject these secrets as environment variables at runtime.
{
"name": "my-app",
// other package.json configuration....
"scaffoldly": {
"secrets": ["SENDGRID_API_KEY", "DATABASE_URL"]
// other scaffoldly configuration...
}
}
Explanation:
- The
secrets
array specifies which match with secrets in GitHub Repository secrets. - Scaffoldly will automatically upload these secrets into the Secret Store during deployment.
- Scaffoldly will inject these secrets as environment variables at runtime.
See: Secrets
name: Scaffoldly Deploy
# other workflow configuration...
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Deploy
uses: scaffoldly/scaffoldly@v1
with:
secrets: ${{ toJSON(secrets) }} # inject repository secrets
Explanation:
- The
secrets
input passes the GitHub repository secrets to the Scaffoldly action. - Scaffoldly will automatically upload these secrets into the Secret Store during deployment.
- Scaffoldly will inject these secrets as environment variables at runtime.
Your application might need to add dotenv
and dotenv-expand
:
const dotenv = require('dotenv');
const dotenvExpand = require('dotenv-expand');
dotenvExpand(dotenv.config());
const dbUrl = process.env.DATABASE_URL;
const sendgridApiKey = process.env.SENDGRID_API_KEY;
Explanation:
- Using
dotenv
anddotenv-expand
, environment variables and secrets can be accessed in your application code. - Secrets are copied from GitHub Actions and re-injected as environment variables during runtime.
Questions, Feedback, and Help
- Join our Discussions on GitHub.
- Join our Community on Discord.