Running locally, with nothing on disk
Binding a directory to a project's environment, running a command with its values, and exactly what orca protects.
A directory is bound to one project's environment once. After that, every
command started through orca run gets that environment's values as
environment variables — nothing is written to disk, and a teammate who
clones the repository and signs in gets the same result with no setup of
their own.
Binding a directory
$ orca link --project payments --env local
Bound this directory to payments/local on api.orcakey.sh (orca.json).
It holds no secrets; commit it.Leave out --project or --env at a terminal and orca link lists what you
can see and asks for a number, rather than making you type a name from
memory.
orca.json holds three names and nothing else:
{ "host": "api.orcakey.sh", "project": "payments", "environment": "local" }Names, not ids: a file one developer commits works for another, and for the same names on a different deployment. It is found by walking up from the current directory to the nearest one, so every directory beneath it shares the binding. There is no layering of more than one environment — a key several projects need is a reference, below, not a second binding.
Running a command
$ orca run -- dotnet run
$ orca run -- npm run dev
$ orca run -- aspire runThe -- is required: everything after it is the command, untouched, so
orca run -- dotnet run --launch-profile https is never ambiguous about
whose --launch-profile that is. Without a binding, or to run against a
different one, name the environment directly:
orca run --env ID -- CMD.
The binding everywhere else
Inside a bound directory, the other commands use the binding too. orca key list, set, generate, rotate and schedule act on the bound environment
when --env is left out, and say which one:
Using payments/local (/src/payments/orca.json). orca auth login signs in
to the binding's deployment, so after cloning a repository nothing else needs
typing. orca auth status adds where the directory is bound and which file
says so. An explicit --env or --host always wins.
The .NET double-underscore convention
ASP.NET Core's configuration binder reads Section:Key from an environment
variable named Section__Key, because : is not legal in most shells' variable
names. Store the value as ConnectionStrings__Default, and
builder.Configuration.GetConnectionString("Default") reads it with no code
change and nothing in appsettings.json — orca run only sets the
variable; the convention is .NET's own.
A key shared by many projects
Keep it once, in a project the others can reference — often called
shared — and point at it from each project that needs it:
$ printf '${shared.local.OPENAI_KEY}' | orca key set OPENAI_KEY --env $Eorca run resolves the reference locally exactly as any other consumer
does: the process receives the resolved value, never the ${...} text.
Change the shared key once, and the next run of every project that
references it picks up the new value — no edit in any of them. If a
reference cannot be resolved (the developer cannot reveal it, or it no
longer exists), nothing starts, and the message names which reference and
why.
When a shell variable is already set
The environment's value wins over one already exported in your shell.
orca run names what it replaced, on its error stream, so "my override
isn't working" has a visible answer:
$ DATABASE_URL=mine orca run -- printenv DATABASE_URL
Replacing from payments/local: DATABASE_URL
postgres://...An environment with no keys says so instead, and still runs:
payments/local has no keys; running with nothing added.
When it will not start
- No binding, and no
--env: how to bind, withorca link. - Not signed in to the binding's deployment: the sign-in command for it.
- A project or environment name that does not exist: the names that do,
and
orca linkto bind again. - An environment that is gone, or not yours to read: exactly that. The two are one answer, as they are everywhere else in orcakey.sh.
- A reference that cannot be resolved: the server's own reason, naming the reference.
- A deployment that cannot be reached: that there is no offline copy to fall back on.
Every one of these exits 1 before the command starts. A partial set of values is never used: either every value resolves, or nothing runs.
Once the command starts, its exit status is orca run's exit status, because
orca run becomes the command: it replaces its own process rather than
starting a child. Ctrl-C, kill and a process manager's stop reach the
command directly, and no orca process is left behind holding a copy of the
values. A command that does not exist exits 127, and one that cannot be
executed exits 126, as they would in a shell.
orca run is not available on Windows yet, and says so.
What is protected, exactly
A value never touches disk, never appears in orca run's own output, and
never lands in the command's arguments, where ps could show it to every
other account on the machine. It exists only inside the command you
started, and inside anything that command itself goes on to start.
That command, and everything it spawns, can read the values it was given
— that is the point: this replaces .env files and dotnet user-secrets, not a way to run code without trusting it with its own
configuration. OrcaKey encrypts values at rest and in transit, and the
deployment can decrypt them: that is how it resolves a reference and hands
this run its values at all. Each key revealed for the run is written to the audit
log once, against the person signed in.