Declaring dependencies
dependencies: source: type: git-repository description: Repository to analyse. mutable: false gcpCredential: type: secret/gcp-service-account required: trueThe contract declares the semantics — what it is. The delivery form comes from the type, and the implementation decides where it shows up.
Core types
Section titled “Core types”| Type | Form | Privilege |
|---|---|---|
directory |
directory | low |
git-repository |
directory | low |
secret |
string | medium |
secret/git-token |
string | medium |
secret/npm-token |
string | medium |
secret/registry-credentials |
file | medium |
secret/gcp-service-account |
file | high |
secret/aws-credentials |
file | high |
secret/coolify-token |
string | high |
engine/docker |
socket | critical |
network |
capability | medium |
What each column decides
Section titled “What each column decides”Three things, and they are orthogonal — which is why eleven types cover almost everything.
Form is how the value crosses into the container, and the runtime does
different work for each:
| Form | What the worker gets |
|---|---|
directory |
a mounted directory, at the mountPath the implementation declares |
file |
a single file, mounted as a secret when the value is content rather than a path |
string |
an environment variable, marked secret when the type is sensitive |
socket |
a Unix socket bound into the container |
capability |
nothing in the filesystem — the grant is the absence of a restriction |
Privilege is what it costs to grant, and it is what the consent gate reads.
Below medium it is granted without asking, because there is nothing to decide
about reading a directory. mutable: true raises it one step: writing into
someone’s directory costs more than reading it.
extends is inheritance. secret/git-token is a secret, and gets a
secret’s treatment — redacted in logs, never written to the host disk.
Why the vocabulary is closed
Section titled “Why the vocabulary is closed”An unknown type is an error, on both sides: the CLI refuses to resolve it, and the portal refuses to publish it.
That is deliberate. This is the one part of the spec that the CLI and the portal
have to interpret identically. If it came from a database or from a file in
your project, two portals would have different vocabularies and the same
oren.yaml would mean different things in each.
Admitting an unknown type would also force assuming a privilege for it — and a privilege assumed downwards is exactly what makes the consent gate stay quiet about something expensive.
Asking for a new type
Section titled “Asking for a new type”A new type is a change to the spec, with a release — not configuration. Before asking, check whether you need one at all:
You probably do not. A credential for another cloud is
form: file, privilege: high, which secret/gcp-service-account already
describes mechanically. What a new name buys is meaning to whoever reads the
contract, and that is a real reason — but it is the only one.
You probably do when the form is new: something that is neither a directory, nor a file, nor a variable, nor a socket, nor a bare capability. That has not happened yet.
What a proposal needs: the name, the form, the privilege and — the part that
matters — why that privilege. engine/docker is critical because the
Docker socket is root on the host; if you cannot write a sentence like that, the
privilege is a guess, and a guessed privilege is worse than no type.
Cardinality
Section titled “Cardinality”The key is the identity; type is an attribute. Declaring several of the
same type is normal:
dependencies: source: { type: git-repository, mutable: true } artifacts: { type: directory, mutable: true } gcpProd: { type: secret/gcp-service-account } gcpStaging: { type: secret/gcp-service-account }mutable
Section titled “mutable”Without it, whatever the worker writes is discarded with the container. With it, the change comes back to the host and later steps see it.
It has to be explicit: it is the difference between a task that reads the repository and one that rewrites the working directory of whoever ran it. And it raises the privilege one level.
In the implementation
Section titled “In the implementation”The contract names; the implementation positions:
dependencies: source: mountPath: /source gcpCredential: mountPath: /secrets/gcp-key.json gitToken: env: GIT_TOKEN # the string form arrives as a variableA key that does not exist in the contract is an additional dependency of the
implementation, and must declare type. That is the delta the catalogue
compares.