API keys
Project Settings → API Keys issues the keys everything outside the console authenticates with. The type select silently rewrites the rest of the form, and nothing on it says what separates the three types.
The type decides how the key is checked
| Type | How it is checked |
|---|---|
| CLI read/write | Holding the key is the permission. Full read and write over the project's files. |
| SDK readonly | Holding the key is the permission. Read-only. |
| Scoped (custom permissions) | The key carries its own permissions and is checked against them on every request. |
For the first two, nothing narrows the key. A scoped key — the type the form opens on — is the only one that can be given less than everything. Project viewers have no API Keys entry in Project Settings, and the console API returns them only the read-only keys an app can ship with: SDK readonly keys and the Browser (read-only) key.
Every new project starts with four keys:
- CLI (CLI read/write) reads and writes everything.
- SDK Development (SDK readonly) reads everything.
- Workflow Execution Key (scoped) reads
dcupl.lc.json,data/**,models/**,transformers/**,operators/**andscripts/**, and writesdata/**andmodels/**. - Browser (read-only) (scoped) reads
dcupl.lc.json,models/**,data/**,transformers/**andoperators/**, and writes nothing.
The Workflow Execution Key's value is also the project variable
dcupl_api_key; it stays on the server. Browser (read-only) is the key for
browser apps: it reads only through the dcupl CDN, and the console API refuses
it (403). Seeded keys don't count toward your plan's key limit (the counter on the API Keys page still includes them). Projects created before these four existed keep the keys they had, which count toward the limit: CLI and SDK Development and, on all but the oldest projects, a Workflow Execution Key that reads only dcupl.lc.json, data/** and models/**.
The Workflow Execution Key is also the key a dcupl Instance step starts
with: a step added in the workflow editor carries the key's id as
config.apiKey in its Init Options, and deploying the workflow resolves the
id to the key, so the step's loader can fetch a private project's files. That is
why the key reads transformers/**, operators/** and scripts/**. A step
written into the template by hand has no key until you add one. On a project
created before the four seeded keys, the preset is that project's own Workflow
Execution Key, which reads only dcupl.lc.json, data/** and models/**; a
project without a key named Workflow Execution Key gets no preset, and its steps
start with no key at all. If such a project is private, put the UID of a key that
reads every file its loader declares in the step.
A key cannot be edited: to change its type or patterns, create a new key and
delete the old one. Replacing the Workflow Execution Key this way leaves the old
value in dcupl_api_key and the old key's id in the workflow steps that use it:
update both, then redeploy those workflows. Set custom value on the form
lets you choose the key string (at least 16 characters; letters, digits, - and
_); otherwise one is generated.
A scoped key carries globs over your files
A scoped key's file read patterns are globs matched against paths in your
project. Its file write patterns cover write, delete, move and copy. The
form starts a scoped key with dcupl.lc.json, data/** and models/** as read
patterns and no write pattern; add transformers/**, operators/** or
scripts/** when the app loads them. Two further switches, Execute
Workflows and Create Runners, are capabilities rather than paths. Execute
Workflows decides which keys a workflow's request trigger can require: the
trigger's key picker lists only scoped keys with it switched on. Create Runners has no effect yet: no service checks it.
A path that no pattern matches is simply left out of the key. There is no warning in the form, because the form does not know what the key will be used for.
The globs must cover everything the app loads
flowchart LR
K["Scoped key"] --> LC["dcupl.lc.json"]
LC --> RES["every declared resource<br/>models · data · transformers · scripts · operators"]
RES --> G{"path matches<br/>a read pattern?"}
G -->|yes| OK["loads"]
G -->|no| FAIL["403 — that resource is missing from the run"]
A project is private when Private CDN is on for it: the CDN then serves its files only to requests that carry one of the project's keys. New projects are private by default. On a project without Private CDN the CDN serves the files without a key, so a scoped key's read patterns do not limit what an app can load. The console does not show the setting. Once on, it stays on through plan changes; a project created before projects became private by default stays public unless its plan includes Private CDN.
A key is only tested when something loads with it. The loader fetches your
dcupl.lc.json and every resource it declares, so on a private project one
uncovered path — a scripts/ folder, say — answers 403 at load time, long
after the key looked fine in this form. The loader records that resource as an
InvalidResource loader error and loads the rest, so the app comes up without
it: no scripts, or a model with no rows. Only an uncovered dcupl.lc.json fails
the whole load. The Browser (read-only) key, for example, does not cover
scripts/**: a browser app whose loader declares script resources under
scripts/ needs a scoped key of its own.
Think about coverage, not syntax. List the resource URLs in your loader config and check each one against the patterns before you save.
Who uses a key
- The SDK — an app loading a private project passes the key to the loader, which appends it to every hosted resource request. A browser app ships its key to every visitor, so give it the Browser (read-only) key (or another scoped key that reads only what the app loads), and keep keys that can write on a server.
- The CLI — a CLI read/write key authenticates
dcupl filespush and pull and thedcupl workflowcommands (deploy,test,history, …); the console API accepts only this key type for workflow deployment. - Workflows — a dcupl Instance step loads the project with the key in its
Init Options (
config.apiKey, preset to the Workflow Execution Key in the editor when the project has one; for another key, put that key's UID, shown in its details on the API Keys page, in its place). A dcupl Files step carries a key of its own. A scoped key needs the matching file patterns. A request trigger with authentication accepts the keys selected on it, and the trigger offers only scoped keys with Execute Workflows. - REST APIs — a deployed instance loads its data with the key configured on
it. The template form's Api Key picker offers SDK readonly keys and scoped
keys that have at least one read pattern (the limit is the picker's: a
template edited as JSON deploys with any key it holds). A scoped key must
cover everything the instance loads. The form warns only when the template has
endpoints and the key cannot read the script files the template's application
schedules (or
scripts/**while it schedules none); it never checks loader data or models.