Choose the authentication boundary
Embedded Node/Python execution needs no AGINDOW credential. Your existing client still supplies vendor credentials. Keyless remote access is for an explicit HTTP execution host; a dashboard session is only for interactive account administration. Fallback API keys are an explicit compatibility or break-glass option and are never required by the embedded SDK.
| Path | Authentication | Setup |
|---|---|---|
| Embedded SDK | No separate AGINDOW credential | Configure the detector in your application. |
| Self-hosted remote execution | Short-lived, sender-bound token | Register a workload and enable the host exchange below. |
| Fallback API keys | Explicit bearer credential | Only for a boundary that explicitly supports the granted scopes. |
1. Prepare the self-hosted execution host
Use a dedicated HTTPS execution origin, separate from your dashboard. The host operator owns /v1/token and /v1/guard, fixed upstream connection bindings and a safe read tool for initial testing. A public-key assertion proves possession of the workload private key; it does not discover an account or grant its own tenant, environment or tools. Live qualification is pending. No managed endpoint or self-service workload registration is currently issued.
2. Register the workload public key
Generate an Ed25519 client key in the workload secret store or host key manager. Give the operator only the public key and key ID. The operator admits an exact registration with private_key_jwt enabled: registration ID, current key ID, issuer and subject equal to the registered client ID, exact assertion audience, allowed access-token audience, tenant, environment, connection and tools. Keep the assertion audience distinct from the output audience agindow:guard. Client assertions require a fresh jti and expire within five minutes; the example uses two minutes. Signing a JWT alone does not register or authorize the workload.
3. Enable host exchange and proof validation
Use the execution-owner host profile with an AUTHORITY SQLite Durable Object binding, EXECUTION_ORIGIN set to the exact HTTPS origin and KEYLESS_ENABLED enabled only after operator review. Install KEYLESS_REGISTRATIONS privately: issuer equal to that origin, not_after no more than one hour ahead, and exact id/kid/x/audience/tenant/environment/connection/tools registrations. Here id is also the client assertion iss/sub, and x is the Ed25519 public JWK coordinate. GUARD_CONNECTIONS binds each tenant/environment/connection/tool to a fixed upstream. The host generates separate ephemeral issuer keys inside each execution owner; never supply the workload private key as a host signing seed. Manual mode requires reviewed refresh outside calls before not_after; expiry returns unavailable. The opt-in automatic mode instead uses a private reviewed policy authority and scheduled job, without an hourly secret replacement. A new or empty owner ledger waits six minutes before exchange. Fallback-key administration material cannot enable this path. The standalone raw Worker uses separate GUARD_IDENTITY_EXCHANGE/GUARD_MACHINE_AUTH snapshots and has process-local replay protection; it does not inherit this owner profile.
Optional automatic registration renewal
Self-hosted operators can select the execution host auto configuration after a stopped, acknowledged cutover. A private authority stores reviewed public-key registrations; a separate scheduled capability renews only unchanged rows every ten minutes. Each admission snapshot expires within one hour and an explicit review mandate lasts at most 30 days. Scope changes, key rotation and expired or revoked authority require a signed operator review or permitted resume, never a workload private key. The operator host runbook describes the private service bindings, offline signing, delivery acknowledgements and reviewer trust rotation. Auto mode never falls back to an old manual secret. If renewal fails, new exchange becomes unavailable at lease expiry; valid existing tokens still use local signature, scope, TTL and epoch checks without renewal I/O. Stopping renewal is not immediate token revocation: stale leases plus the last token can remain valid for a conservative 66 minutes under the clock assumptions. KEYLESS_ENABLED=false is a separate execution stop whose deployment propagation must be verified. Local fixtures cover renewal and failures; live control-plane qualification remains pending. Client SDK setup below is unchanged.
4. Configure the Node client
Install the published Node SDK through its version-pinned installation guide. Save this helper in your application and call connectSelfHosted with the operator-issued HTTPS exchangeEndpoint, registration, clientId, kid, exact assertion audience, a privateKeyFile readable only by your workload, and admitted tools. The helper loads the key at setup and signs a fresh assertion on each background acquisition. It creates an independent ephemeral DPoP proof key; do not register that ephemeral key as the client assertion key or print tokens/headers.
import { readFile } from 'node:fs/promises';
import { createPrivateKey, randomUUID, sign } from 'node:crypto';
import { createRemoteAuth, workloadIdentity } from 'agindow';
export async function connectSelfHosted(options: {
exchangeEndpoint: string; registration: string;
clientId: string; kid: string; audience: string;
privateKeyFile: string; tools: string[];
}) {
// This is the workload's key, held outside model context and source control.
const key = createPrivateKey(await readFile(options.privateKeyFile));
if (key.asymmetricKeyType !== 'ed25519') throw Error('Ed25519 client key required');
const encode = (value: object) => Buffer.from(JSON.stringify(value)).toString('base64url');
return createRemoteAuth({
acquire: workloadIdentity({
exchangeEndpoint: options.exchangeEndpoint,
registration: options.registration, tools: options.tools,
assertion: async () => {
const now = Math.floor(Date.now() / 1000);
const header = encode({ alg: 'EdDSA', typ: 'JWT', kid: options.kid });
const claims = encode({ iss: options.clientId, sub: options.clientId,
aud: options.audience, iat: now, nbf: now, exp: now + 120, jti: randomUUID() });
const input = header + '.' + claims;
return input + '.' + sign(null, Buffer.from(input), key).toString('base64url');
},
}),
});
}5. Call the remote guard explicitly
Pass the returned session as auth to guardRemote(original, envelope, { endpoint, auth }), using the full /v1/guard endpoint and its registered connection/tool. Start with a read in observe mode and inspect the returned Response once. Always close auth when the workload shuts down. The SDK acquires/refreshes credentials outside guard calls and creates local request proofs. Keep legacy fallback disabled; do not pass apiKey alongside auth. Writes still require the same upstream-enforced idempotency key across any documented fallback.
Python client
Use RemoteAuth(workload_identity(exchange_endpoint=..., registration=..., tools=(...), assertion=...), signer), then RemoteOptions(endpoint=..., auth=auth) with guard_remote or guard_remote_async. Supply an assertion callback that signs fresh Ed25519 JWTs with the same registered iss/sub/aud/kid and a new jti, and a separate ProofSigner(public_x, sign) for DPoP. The sign callback returns a 64-byte Ed25519 signature through your host cryptographic library or key manager. Python does not generate or store the private proof key for you. Close RemoteAuth after use. Do not use a permanent assertion file without an external rotation process.
6. Verify admission and recovery
A valid read must reach the configured upstream through the authenticated host without using the original fallback. A stolen token with another proof key, replayed proof/assertion, wrong tenant/environment/audience or excess tool scope must be refused before dispatch. Verify key rotation, snapshot expiry, exchange outage and SDK background refresh. Setup failure is distinct from a runtime bypass; known authentication rejection is not permission to execute the original binding. Do not log credentials as evidence.
Qualification and replay limits
Local compiled-Worker tests can verify the exact Node helper, exchange, DPoP, refusal and refresh behavior with synthetic upstream reads. They do not qualify a public deployment or an external OIDC provider. The execution-owner profile routes all token, guard, delegation and audit/outcome requests for an immutable registration to one execution owner. Durable assertion fences reject reuse after restart. Lost local proof state rotates the issuer epoch, invalidating earlier tokens with 503 until background refresh obtains a new token. Lost assertion storage triggers a six-minute waiting period. Local multi-ingress tests cover races, restarts, verifier resets, retention capacity, clock rollback and retrieval; live deployment, partition/failover and latency qualification remain pending. Replay/rate fences in the standalone raw Worker and sidecar remain process-local. A successful token exchange, a dashboard link or a sticky router alone is insufficient. Detection calibration, repair and durable outcome storage remain separate qualifications.