Vault-backed secrets: management, sandbox bindings, and resolution.
Secrets hold sensitive values server-side; sandboxes mount them as
environment variables through bindings (%{"ENV_VAR" => "secret-name"}),
so plaintext never travels through ordinary sandbox metadata:
{:ok, secret} = ExDaytona.Secrets.create(client, "db-prod", "s3cr3t")
{:ok, sandbox} =
ExDaytona.Sandbox.create(client, secrets: [%{"DB_PASSWORD" => "db-prod"}])
# or later, replacing the mounted set:
{:ok, _} = ExDaytona.Secrets.set_sandbox_bindings(sandbox, [%{"DB_PASSWORD" => "db-prod"}])Inside the sandbox, a bound env var does not contain the plaintext:
it carries a placeholder handle (dtn_secret_...); the real value is
materialized by the platform according to the secret's hosts
allowlist (verified against the live API). resolve/1 is the
operator-side view that returns actual values.
Every value-bearing input and result renders redacted under
inspect/1 — resolved plaintext is reachable only by reading struct
fields explicitly.
Summary
Functions
Create a secret. Options: :description, :hosts (list of hosts the
secret may be exposed to).
Delete a secret. Returns :ok.
Fetch a secret's metadata by id (values are never returned here).
List secrets with pagination. Accepts :cursor, :limit, :name,
:sort, :order; returns
{:ok, %{items: [%ExDaytona.Model.Secret{}], next_cursor: cursor, total: n}}.
Resolve the sandbox's secret bindings. Returns
ExDaytona.Model.ResolveSandboxSecrets200ResponseInner structs whose
value fields are redacted under inspect/1 — plaintext is only
reachable by reading .value explicitly.
Replace the sandbox's mounted secret set with bindings — a list of
single-entry maps %{"ENV_VAR" => "secret-name"}. Pass [] to detach
all secrets. Returns the updated sandbox.
Update a secret. Options: :value, :description, :hosts — only the
given fields change.
Functions
@spec create(ExDaytona.Client.t(), String.t(), String.t(), keyword()) :: {:ok, ExDaytona.Model.Secret.t()} | {:error, ExDaytona.Error.t()}
Create a secret. Options: :description, :hosts (list of hosts the
secret may be exposed to).
@spec delete(ExDaytona.Client.t(), String.t()) :: :ok | {:error, ExDaytona.Error.t()}
Delete a secret. Returns :ok.
@spec get(ExDaytona.Client.t(), String.t()) :: {:ok, ExDaytona.Model.Secret.t()} | {:error, ExDaytona.Error.t()}
Fetch a secret's metadata by id (values are never returned here).
@spec list( ExDaytona.Client.t(), keyword() ) :: {:ok, %{ items: [ExDaytona.Model.Secret.t()], next_cursor: String.t() | nil, total: non_neg_integer() | nil }} | {:error, ExDaytona.Error.t()}
List secrets with pagination. Accepts :cursor, :limit, :name,
:sort, :order; returns
{:ok, %{items: [%ExDaytona.Model.Secret{}], next_cursor: cursor, total: n}}.
@spec resolve(ExDaytona.Sandbox.t()) :: {:ok, [ExDaytona.Model.ResolveSandboxSecrets200ResponseInner.t()]} | {:error, ExDaytona.Error.t()}
Resolve the sandbox's secret bindings. Returns
ExDaytona.Model.ResolveSandboxSecrets200ResponseInner structs whose
value fields are redacted under inspect/1 — plaintext is only
reachable by reading .value explicitly.
Authentication
This endpoint authenticates platform infrastructure (the component
that materializes secret values) — with a regular user API key it
returns 403 "Invalid authentication context" (verified live).
User code sees only placeholder handles inside the sandbox.
@spec set_sandbox_bindings(ExDaytona.Sandbox.t(), [map()]) :: {:ok, ExDaytona.Sandbox.t()} | {:error, ExDaytona.Error.t()}
Replace the sandbox's mounted secret set with bindings — a list of
single-entry maps %{"ENV_VAR" => "secret-name"}. Pass [] to detach
all secrets. Returns the updated sandbox.
@spec update(ExDaytona.Client.t(), String.t(), keyword()) :: {:ok, ExDaytona.Model.Secret.t()} | {:error, ExDaytona.Error.t()}
Update a secret. Options: :value, :description, :hosts — only the
given fields change.