Configuration and Credentials
Declare, resolve, deliver, and audit configuration and credentials without ambient secrets.
Configuration may be contextual. Credentials are capability-scoped.
Assembly Line separates four kinds of runtime input:
| Category | Examples | Consumer |
|---|---|---|
| Runtime configuration | API base URLs, regions, feature flags | Only the declaring tool, connection, channel, provider, or instrumentation module |
| Gateway/bootstrap credentials | Model-provider and runtime control-plane authentication | Trusted gateway code only |
| Connection credentials | API keys, OAuth grants, service-account tokens | One active, authorized connection |
| Sandbox credentials | Short-lived tokens or credential files requested for one run | One sandbox and, where possible, one process |
Connection metadata uses requiredConfig, optionalConfig,
requiredCredentials, and optionalCredentials. The removed requiredEnv,
optionalEnv, stdio hostEnv, and relay credentialEnv fields are not
accepted. A URL belongs in configuration; a token belongs in credentials.
Runtime lifecycle
The runtime owns one credential broker backed by the selected secret store and connection grant store. When an authorized connection operation runs, the runtime:
- creates the connection with only its declared configuration;
- gives its reviewed factory a scoped credential accessor;
- resolves a requested, declared credential just in time;
- applies the connection subject, principal, audience, and grant rules;
- delivers the value only through the requested transport; and
- records value-free audit metadata.
The accessor has get(name, { purpose, delivery }) and
optional(name, { purpose, delivery }). It rejects undeclared names before
consulting the store. It never exposes a complete secret map. Audits record the
logical credential, connection, run, principal, purpose, delivery, outcome,
and expiration when available—never the value.
Connection definitions are runtime-owned factories. They must not read
provider credentials from process.env at import time or during definition
creation. A configured secret can therefore rotate and be resolved on the next
use without rebuilding unrelated connections.
Authored tools
Authored tools receive declared non-secret values through read-only
ctx.config. They do not receive ctx.channel.env, a credential accessor, or
the host's complete environment. Production Node hosts run authored tools in
the selected sandbox by default. Direct execution is an explicit embedding-host
choice for reviewed code that belongs to the trusted computing base; it still
does not add a generic secret map to the tool context.
For example, a tool may declare and read a base URL:
export default {
tools: {
catalog_status: {
definition: "./catalog-status.ts",
description: "Check the configured catalog endpoint.",
inputSchema: { type: "object" },
requiredConfig: ["CATALOG_API_URL"]
}
}
};export default defineTool({
description: "Check the configured catalog endpoint.",
inputSchema: { type: "object" },
execute: async (_input, ctx) => ({ endpoint: ctx.config.CATALOG_API_URL })
});Provider authentication belongs in a connection, not an authored tool.
Deploy capabilities follow the same rule. Static provider policy marks each environment preflight entry as configuration or credential. After evaluating conditions against the compiled manifest, the host broker resolves only the active credential entries for the selected deploy target. Configuration stays in the non-secret runtime view, and an unrelated or inactive deploy credential cannot cross that boundary.
Connection examples
HTTP
The static contract classifies the endpoint separately from its bearer token:
{
"protocol": "http",
"provider": "acme",
"baseUrlEnv": "ACME_API_URL",
"tokenEnv": "ACME_API_TOKEN",
"requiredConfig": ["ACME_API_URL"],
"optionalConfig": [],
"requiredCredentials": ["ACME_API_TOKEN"],
"optionalCredentials": []
}defineHttpApiPluginConnection() resolves the URL from the scoped config and
the bearer token through the broker for each request. Header values are applied
host-side and are not model arguments or results.
SDK
A reviewed SDK connection asks for exactly the credential it needs:
return defineSdkApiPluginConnection(metadata, {
operations,
execute: async (operation, input, context) => {
const apiKey = await context.credentials.get("ACME_API_KEY", {
purpose: `Acme ${operation}`,
delivery: "sdk"
});
return createAcmeClient({
baseUrl: context.config.ACME_API_URL,
apiKey,
fetch: context.fetch
}).execute(operation, input);
}
});Stdio MCP
A stdio plugin uses the same public declaration:
{
"protocol": "mcp",
"transport": "stdio",
"requiredConfig": ["ACME_REGION"],
"optionalConfig": [],
"requiredCredentials": ["ACME_API_KEY"],
"optionalCredentials": []
}The runtime launches the reviewed command with only portable process basics,
the connection's declared configuration, and its declared credentials. An
unrelated runtime secret is absent. env on the factory is for reviewed,
non-secret literal process settings; it is not a host-environment projection.
CLI credential leases
A CLI that genuinely needs credentials uses a credential connection with a
reviewed materialize definition. Host code requests it by connection and
purpose in the run input—for example:
await runtime.runAgent({
message: "Update the repository.",
sandboxCredentials: {
github_app: {
repository: "acme/widgets",
capability: "contents:write"
}
}
});Resolved files must stay under
/workspace/.assembly-line/credentials/. That root is excluded from workspace
sync, versions, checkpoints, and durable snapshots. A requested unavailable
credential fails the run closed. An unavailable credential that the run did
not request is reported as pending and does not block unrelated sandbox work.
Prefer short-lived or derived credentials and deliver them to one process when
the provider supports it.
Secure browser credential fill
A trusted credential source can transfer a value directly to a trusted sink. The model supplies identifiers and intent only:
{
"source_connection": "onepassword",
"reference": "op://Charlie/PeerComps/password",
"target": { "computer_id": "charlie-browser" },
"purpose": "Sign in to PeerComps"
}Calling orgo__credential_fill causes the host to resolve the reference with
the 1Password connection and type it into the focused field through the Orgo
connection. Neither the model nor authored tool code receives the value. The
only successful result is:
{ "status": "filled" }Failures return a generic transfer error; provider errors that echo the value are discarded. After the fill, the agent continues with ordinary Orgo browser operations.
1Password roles
The 1Password secrets provider supplies host-side credentials to the broker.
The 1Password connection is a trusted credential source for host-to-host
transfer. Its default model-facing tools list and search vault/item metadata;
they do not return concealed fields, complete items, or arbitrary
resolve_secret results. Use separate service accounts and vault scopes for
gateway storage and any model-visible metadata browsing.
Migration
Remove ambient environment dependencies instead of wrapping them:
- move shared non-secret
.envvalues to typedconfig.production.tsand use the shell only for local overrides; the CLI no longer loads project.env; - replace
requiredEnvandoptionalEnvwith explicit config and credential lists; - move provider API calls that need credentials from authored tools into reviewed connections;
- replace
ctx.channel.envwithctx.configfor declared non-secret values; - replace stdio
hostEnvand relaycredentialEnvwith generic connection credential declarations; - stop reading provider secrets from
process.envin connection packages; - treat direct authored-tool execution as an explicit trusted-host exception, not the production default; and
- use credential materialization or source-to-sink transfer when a sandbox process or browser must consume a secret.
Redaction remains defense in depth. The primary boundary is that raw values do not enter prompts, tool arguments/results, run state, events, logs, traces, workspace files, or sandboxes that did not explicitly request them.