Projects
Project secrets
Store runtime credentials as encrypted, read-only files, select secrets to copy with the CLI, and check mount-refresh results.
What project secrets are for
Project secrets are named values that are available to code running in a project without committing private tokens into notebooks, scripts, terminals, or TimeTravel history.
Use them for API keys, access tokens, deployment credentials, and other values that code needs at runtime but should not be stored in project files.
Secrets are encrypted at rest in the database and mounted into running projects
as read-only files under /run/secrets/cocalc/<name>. They are not stored in
project files, snapshots, backups, rootfs images, downloads, or public shares.
Add a secret from the UI
- Open the project.
- Open Settings.
- Go to Environment.
- Choose Secrets.
- Add a name and value, then save it.
The exact UI action is identified as settings.environment.secrets. The docs
system will use these action ids so Codex and other agents can open the right
panel in the current browser session instead of merely describing where to
click.
Adding, replacing, deleting, or copying a secret refreshes the mounted files in a running project immediately. You do not need to restart the project. A program that already read and cached a secret may still need its own reload. If the project is stopped, it receives the latest secrets the next time it starts; if a live refresh cannot reach the project host, the Secrets panel reports that the refresh is pending and offers a retry.
Use the secret
Secrets are files, not environment variables. In a terminal, notebook, or
script, read the value from the mounted secret file. Use the
COCALC_SECRETS environment variable instead of hardcoding the directory.
import os
from pathlib import Path
secrets_dir = Path(os.environ["COCALC_SECRETS"])
token = (secrets_dir / "MY_API_TOKEN").read_text().strip()
Use clear uppercase names such as OPENAI_API_KEY, HF_TOKEN, or
DATABASE_URL. Any code or collaborator with access to the running project
can read these files, so avoid putting secret values in source files, notebook
outputs, chat messages, logs, or command history.
SSH private keys usually need a final newline. If you paste one manually, use the warning in the Secrets dialog to add the newline before saving.
Choose secrets or ordinary environment variables
Use Custom Environment Variables for non-secret configuration. After an authorized update is saved, restart the project for those values to take effect in terminals, Jupyter kernels, and other processes. API keys, private keys, and tokens belong in Project Secrets. An authorized, saved secret update can refresh the mounted files without restarting the project; check the refresh result below. A secret-file refresh does not reload a value that an application already cached.
Manage secrets with the CLI
Run these commands in a terminal with the CoCalc CLI installed and
authenticated to the intended site as an account allowed to manage the selected
projects. Start with CLI setup and
Authentication and targets. Replace
TARGET_PROJECT_ID and SOURCE_PROJECT_ID below with the intended projects.
Copying requires collaborator access to both projects.
Validation (2026-09-11): the list, set, copy, and delete help was checked with CoCalc CLI 1.0.3. At source revision b024f77, 17 command-registration checks passed with Commander 14.0.1 and synthetic project and service adapters. These examples describe reference syntax and selection behavior. Authenticated transfers, server enforcement, mount refresh, and application reloads have not been exercised by these checks.
These commands inspect metadata and available options:
cocalc project secrets list --project TARGET_PROJECT_ID --json
cocalc project secrets set --help
cocalc project secrets copy --help
list returns secret metadata, such as names and sizes, rather than secret
values. set NAME adds or replaces one secret and requires exactly one input
source: --value, --file, or --stdin. Prefer a protected input file or stdin
when supplying a credential so its value is not written into the command line.
Course-managed secrets cannot be changed using generic set, delete, or
copy --overwrite commands.
To copy an existing secret named DOCS_EXAMPLE, explicitly select its source,
destination, and name. This command writes to the destination project:
cocalc project secrets copy --from SOURCE_PROJECT_ID --project TARGET_PROJECT_ID --name DOCS_EXAMPLE --json
DOCS_EXAMPLE is an example name; the command does not create a source secret.
Omitting --name requests all secrets from the source project. Use explicit
names when only some credentials belong in the destination. Add --overwrite
only when you intend to replace matching destination names; replacement is off
by default.
Inspect the command's result fields before continuing:
| Field | Meaning |
|---|---|
copied |
Names copied by this request. |
conflicts |
Destination names that prevented a copy without --overwrite. |
missing |
Requested names absent from the source. |
If conflicts or missing is nonempty, copied is empty: the request does not
skip the problem names and copy the rest. Resolve the names or replacement
choice deliberately before trying again. Listing destination metadata can
confirm which names exist; it does not reveal their values or prove an
application is using them.
Check the mount separately from the application
A successful change can include a runtime_refresh result. The status
cached_for_next_start means the saved secrets will be mounted on the next
start; retry_pending means the runtime refresh has not been confirmed. In the
Secrets panel, use Retry mount refresh when that action is offered.
After the mount is current, reload an application that cached the old value and
verify its expected behavior without printing the credential.
cocalc project secrets delete NAME --project TARGET_PROJECT_ID removes a
project secret. Removing or replacing that mounted value does not revoke the
credential at its external issuer; handle issuer-side revocation separately.
Why this matters in CoCalc
CoCalc projects are collaborative, durable, and agent-friendly. That is exactly why secrets should have a first-class home: humans and agents can run code, restart terminals, execute notebooks, and automate tasks without turning private credentials into shared document content.