The credential boundary is the CredentialProvider interface. The stock server selects one of the built-in implementations from EYEBALL_CREDENTIALS; when you call createExecutorApp yourself you can pass any implementation, including your own.

Environment provider

EnvCredentialProvider maps toolkit-specific environment variables into API key, OAuth2, Basic, or no-auth credentials. This is the same implementation the stock server constructs for EYEBALL_CREDENTIALS=env. In stock mode the variable names come from the catalog defaults documented in Connect real providers; every referenced variable starts with:

Text
EYEBALL_CRED_<TOOLKIT_SLUG_UPPERCASE>_

Embedding the engine lets you supply a custom mapping instead of the catalog defaults:

js
import { EnvCredentialProvider } from "@eyeball/core";
import { ExecutionEngine, createExecutorApp } from "@eyeball/executor";

const credentials = new EnvCredentialProvider({
  allowedProjectId: "proj_internal",
  allowedUserId: "service_account",
  mappings: {
    stripe: {
      type: "api_key",
      valueEnvs: { apiKey: "EYEBALL_CRED_STRIPE_API_KEY" },
    },
  },
});

const engine = new ExecutionEngine({ credentialProvider: credentials });
const app = createExecutorApp({ engine });

The provider refuses every other project/user pair. This is appropriate for a controlled single-service identity, not multi-tenant end-user OAuth. Rotation, encryption at rest, consent, and refresh orchestration remain your responsibility.

Local encrypted vault

LocalVaultCredentialProvider is the durable, encrypted file provider the stock server constructs for EYEBALL_CREDENTIALS=local-vault. Prefer configuring it through the stock server and the eyeball-auth CLI as described in Connect real providers; construct it directly only when embedding the engine.

Development fixture vault

InMemoryDevVault is both a CredentialProvider and the implementation behind the optional /v1/connections routes used by the dev stack. It is a development seam only — never expose it in a production multi-tenant service:

js
import { InMemoryDevVault, createExecutorApp } from "@eyeball/executor";

const devVault = new InMemoryDevVault({
  credentials: {
    gmail: {
      type: "oauth2",
      accessToken: "fixture:valid",
      scopes: ["https://www.googleapis.com/auth/gmail.modify"],
    },
  },
});
const app = createExecutorApp({ devVault });

It accepts only preconfigured fixture templates, loses all connections on restart, and cannot refresh, encrypt, or run OAuth. The executor enforces that the engine and dev connection routes share the same vault instance.