Secrets and environment variables
Secrets are encrypted values injected into workflow jobs as environment variables. They are write-only after creation. The value is never readable back through the UI or API. This page covers scopes, creation, workflow usage, rotation, and limits.
Secrets are encrypted at rest with T Cloud DEW KMS and decrypted only at job execution time on the runner.
Org-level secrets ship as a first-class fremforge admin tab at frem.sh/<org>/_admin/secrets (created 2026-05-10). Repo-level and environment-level secrets remain in Forgejo native UI under each repo’s Settings → Secrets and Settings → Environments → <env> → Secrets, that’s where Forgejo’s per-repo and per-environment scopes live, and the precedence model (environment → repo → org) is enforced by Forgejo at job execution time.
Scopes
| Scope | Where set | Available to |
|---|---|---|
| Org secret | Org admin → Secrets | All repos in the org |
| Repo secret | Repo Settings → Secrets | That repo only |
| Environment secret | Repo Settings → Environments → <env> → Secrets | Jobs that declare environment: <env> |
Precedence: environment secret overrides repo secret overrides org secret. When the same name exists at multiple scopes, the most specific scope wins.
Creating secrets
Via the UI: navigate to the appropriate scope → New secret → enter name (UPPER_SNAKE_CASE convention) and value → Save.
Via the API:
# Org secret
curl -X PUT \
-H "Authorization: Bearer <PAT>" \
-H "Content-Type: application/json" \
-d '{"name":"MY_SECRET","data":"the-value"}' \
https://frem.sh/api/v1/orgs/<org>/actions/secrets/MY_SECRET
# Repo secret
curl -X PUT \
-H "Authorization: Bearer <PAT>" \
-H "Content-Type: application/json" \
-d '{"name":"MY_SECRET","data":"the-value"}' \
https://frem.sh/api/v1/repos/<org>/<repo>/actions/secrets/MY_SECRETSecrets are write-only after creation. You cannot read back a secret value through the API or UI. You can only overwrite or delete.
Using secrets in workflows
Reference secrets with ${{ secrets.NAME }}. Secrets are available as environment variables.
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
steps:
- name: Deploy
env:
API_KEY: ${{ secrets.DEPLOY_API_KEY }}
run: ./deploy.shSecrets are masked in logs: any log output that exactly matches a secret value is replaced with ***. Masking applies to exact matches only; base64-encoded, URL-encoded, or otherwise transformed variants of the secret value are not automatically masked.
Environment secrets and deployment gates
Jobs that declare environment: only receive secrets scoped to that environment (plus repo and org secrets). This is intentional: environment secrets gate production credentials behind the environment’s approval flow.
jobs:
deploy-prod:
runs-on: fremforge
environment: production # triggers approval gate if reviewers are configured
steps:
- name: Deploy
env:
DB_URL: ${{ secrets.PROD_DB_URL }} # environment secret on 'production'
run: ./deploy.shConfigure required reviewers under Repo Settings → Environments → <env>. The job pauses for approval before the step runs; the secret is not injected until the job is approved and executing.
Secret rotation
- Create the new credential in the external system first.
- Overwrite the secret in fremforge with the new value. Do not delete and recreate.
- Trigger a new workflow run to verify the new credential works end-to-end.
- Revoke the old credential in the external system.
Overwriting preserves the audit trail and avoids a window where the secret is missing from jobs running between delete and recreate.
Limits
| Item | Limit |
|---|---|
| Max secret value size | 64 KB |
| Org secrets | 1,000 |
| Repo secrets | 100 per repo |
| Environment secrets | 100 per environment |
| Secret name pattern | Alphanumeric and underscore; must start with a letter; cannot start with FORGEJO_ or GITHUB_ |
OIDC as a secret alternative
For deploying to cloud providers (T Cloud, AWS, Azure, GCP), consider OIDC token federation instead of long-lived credentials stored as secrets. OIDC issues short-lived tokens per job, scoped to the specific workflow run. Nothing to rotate, nothing to leak.
OIDC is the recommended pattern for any job that deploys to cloud infrastructure.
Cross-references
- Actions and CI/CD, workflow syntax and permissions block
- OIDC token federation, keyless cloud credentials
- Org admin, org-level secrets management