# The `seekrit-run` launcher

`seekrit-run` is a compiled, single-file version of `seekrit run` built for
machines. It authenticates with a service token, fetches the bound
environment's encrypted secrets, **decrypts them locally**, layers them under
any `.env` files and the live process environment, and then `exec`s your
command. That's all it does — no config files, no caching, no daemon.

```bash
SEEKRIT_TOKEN=skt_… seekrit-run -- ./start-server
```

> **Note:** Use the Node `seekrit` CLI for human workflows (login, key setup, managing secrets). `seekrit-run` is **service-token only** and read-only at runtime: the smallest thing that can turn a token into an environment and hand off to your process.

## Degrades gracefully

Fetching seekrit secrets is **best-effort**. If the token is missing or
malformed, or the API can't be reached, `seekrit-run` logs a warning to stderr
and still runs your command with just the `.env` overlay and the live
environment:

```
seekrit-run: continuing without seekrit-managed secrets: could not reach the seekrit API: …
```

This means the same launcher works whether or not seekrit is reachable — locally
without a token, in CI, or in an offline sandbox — so you can wire it into an
image's entrypoint unconditionally. Only genuinely local problems stop it: a
usage error, an explicit `--env-file` that can't be read, or a command that
can't be started. The `seekrit run` subcommand of the Node CLI behaves the same
way.

## Why use it instead of the CLI?

- **Tiny & static.** One ~1–2 MB file with no runtime dependencies — no Node,
  no OpenSSL, no system CA bundle. TLS roots are compiled in, so it runs
  unchanged in `distroless`, `alpine`, and `scratch` images.
- **Same behavior as `seekrit run`.** Identical layer precedence and `.env`
  parsing; its decryption is verified bit-for-bit against the browser/CLI
  crypto.
- **Clean process model.** On Unix it replaces itself with your command
  (`execvp`), so signals and exit codes pass through exactly. On Windows it
  spawns, waits, and forwards the exit code.

## Install

The install script detects your OS and architecture, downloads the matching
binary from `run.seekrit.dev`, verifies its SHA-256 checksum, and drops it on
your `PATH`:

```bash
curl -fsSL https://run.seekrit.dev/install.sh | sh
```

It installs to `/usr/local/bin` if that's writable, otherwise `~/.local/bin`.
Override the destination, pin a version, or force a target with environment
variables:

```bash
# Pin a version and install somewhere specific.
curl -fsSL https://run.seekrit.dev/install.sh \
  | SEEKRIT_RUN_VERSION=0.2.0 SEEKRIT_RUN_INSTALL_DIR="$HOME/bin" sh
```

| Variable | Default | Description |
| --- | --- | --- |
| `SEEKRIT_RUN_VERSION` | `latest` | Version to install, e.g. `0.2.0`. |
| `SEEKRIT_RUN_INSTALL_DIR` | `/usr/local/bin` or `~/.local/bin` | Where to put the binary. |
| `SEEKRIT_RUN_TARGET` | auto-detected | Force a Rust target triple. |

### Manual download

Prefer to fetch it yourself? Every release is published under a versioned and a
`latest/` path, each with a `.sha256` alongside. On Linux the fully static
**musl** build runs anywhere (glibc, `alpine`, `distroless`, `scratch`):

```bash
# Pick your target: {x86_64,aarch64}-{unknown-linux-musl,unknown-linux-gnu,apple-darwin}
curl -fsSL -O https://run.seekrit.dev/latest/seekrit-run-aarch64-apple-darwin.tar.gz
curl -fsSL -O https://run.seekrit.dev/latest/seekrit-run-aarch64-apple-darwin.sha256
shasum -a 256 -c seekrit-run-aarch64-apple-darwin.sha256
tar xzf seekrit-run-aarch64-apple-darwin.tar.gz
install -m 0755 seekrit-run /usr/local/bin/
```

Windows ships as a `.zip` (`seekrit-run-x86_64-pc-windows-msvc.zip`).

## Usage

```bash
# Token from the environment (or a .env file); resolves org/app/env from it.
SEEKRIT_TOKEN=skt_… seekrit-run -- pnpm start

# Token via flag; everything after -- is the command, verbatim.
seekrit-run --token skt_… -- node --enable-source-maps server.js

# Point at a self-hosted API.
seekrit-run --api-url https://api.your-seekrit.example -- ./app

# Swap one composed group's slice for this run.
seekrit-run --with auth-providers=staging -- ./app

# See where each variable resolved from (stderr; names only, never values).
seekrit-run --explain -- true
```

## Precedence

Highest wins — identical to `seekrit run`:

```
process env  >  .env files  >  app-environment secrets  >  group secrets
```

The live process environment always wins, so a value exported in the shell (or
by your orchestrator) overrides anything seekrit resolves.

## Options

| Flag | Default | Description |
| --- | --- | --- |
| `-t, --token <skt_…>` | `SEEKRIT_TOKEN` (env or `.env`) | Service token. |
| `--api-url <url>` | `SEEKRIT_API_URL` or `https://api.seekrit.dev` | API base URL. |
| `-e, --env-file <path>` | `.env` | A `.env` file to overlay (repeatable). |
| `--no-env-file` | | Do not load the default `.env`. |
| `--with <group=env>` | | Override one composed group's slice (repeatable). |
| `--explain` | | Print each variable's source to stderr. |

`HTTPS_PROXY` / `ALL_PROXY` are honored for egress-proxied networks.

## In a container

Keep Node out of your runtime image entirely — fetch the static binary in a
build stage (pin the version and verify the checksum for reproducible images),
then copy it into a minimal runtime and make it the entrypoint:

```dockerfile
# --- fetch seekrit-run: pinned + checksum-verified --------------------------
FROM alpine:3 AS seekrit
ARG SEEKRIT_RUN_VERSION=0.2.0
ARG TARGET=x86_64-unknown-linux-musl
RUN apk add --no-cache curl && cd /tmp \
 && curl -fsSL -O https://run.seekrit.dev/v${SEEKRIT_RUN_VERSION}/seekrit-run-${TARGET}.tar.gz \
 && curl -fsSL -O https://run.seekrit.dev/v${SEEKRIT_RUN_VERSION}/seekrit-run-${TARGET}.sha256 \
 && sha256sum -c seekrit-run-${TARGET}.sha256 \
 && tar xzf seekrit-run-${TARGET}.tar.gz -C /usr/local/bin

# --- your runtime image: fully static, so distroless/static is enough -------
FROM gcr.io/distroless/static
COPY --from=seekrit /usr/local/bin/seekrit-run /usr/local/bin/seekrit-run
ENTRYPOINT ["seekrit-run", "--"]
CMD ["./start-server"]
```

```bash
docker run --rm \
  -e SEEKRIT_TOKEN="$SEEKRIT_TOKEN" \
  your-image ./start-server
```

> **Warning:** Inject at runtime, never at build time. Secrets fetched during `docker build` can be baked into an image layer. `seekrit-run` only ever puts values into the child process's environment — nothing touches disk.

## Exit codes

| Code | Meaning |
| --- | --- |
| `2` | Usage error (unknown flag, no command). |
| `1` | An explicitly named `--env-file` could not be read. |
| `127` | The command could not be started. |
| _child_ | Otherwise, the command's own exit code. |

A missing/malformed token, a revoked token or missing key grant, and network
failures are **not** fatal — `seekrit-run` warns and runs the command without
the managed secrets (see [Degrades gracefully](#degrades-gracefully)).

See the [CLI reference](/docs/reference/cli#seekrit-run-launcher) for the
condensed version, and [Service tokens](/docs/guides/service-tokens) for how to
mint the token this binary needs.
