Appearance
Credential references
A credential reference is anything that lets a caller use a credential without seeing its bytes. The Matrix pattern is a two-step lease:
- Caller asks Factotum for a
leaseId. - A trusted system actor exchanges the
leaseIdfor HTTP headers ready to send to the provider.
The raw token never crosses the bus.
The two ops
Source: projects/matrix-3/packages/system-factotum/dist/index.js.
credential.lease
ts
// system-factotum/dist/index.js:557-587
async onCredentialLease(payload): Promise<Result> {
if (!payload.provider) return { ok: false, error: 'provider is required' };
const credential = this._fileStore.getProvider(payload.provider);
if (!credential) {
this.emit('factotum.needkey', { provider: payload.provider, requestedBy: 'unknown' });
return { ok: false, error: `No credential found for provider: ${payload.provider}` };
}
const leaseId = this._generateLeaseId();
const expiresAt = Date.now() + LEASE_TTL_MS; // 5 minutes
this._leases.set(leaseId, {
provider: payload.provider,
scope: payload.scope ?? 'infer',
rootId: ctx?.rootId ?? 'local',
createdAt: Date.now(),
expiresAt,
});
return {
ok: true,
leaseId, // 32-hex string
provider: payload.provider,
type: credential.type, // 'oauth' | 'api-key' | 'local'
expiresAt,
scope,
};
}The lease is recorded in an in-memory map. It expires in 5 minutes (LEASE_TTL_MS). A cleanup timer prunes expired leases every minute.
credential.materialize
ts
// system-factotum/dist/index.js:593-628
async onCredentialMaterialize(payload): Promise<Result> {
if (!payload.leaseId) return { ok: false, error: 'leaseId is required' };
const lease = this._leases.get(payload.leaseId);
if (!lease) return { ok: false, error: 'Lease not found or expired' };
if (Date.now() > lease.expiresAt) {
this._leases.delete(payload.leaseId);
return { ok: false, error: 'Lease expired' };
}
const credential = this._fileStore.getProvider(lease.provider);
if (!credential) {
this._leases.delete(payload.leaseId);
return { ok: false, error: 'Credential no longer available' };
}
const headers = {};
let baseUrl;
if (credential.type === 'api-key' && credential.apiKey) {
if (lease.provider === 'anthropic') {
headers['x-api-key'] = credential.apiKey;
headers['anthropic-version'] = '2023-06-01';
} else if (lease.provider === 'openai' || lease.provider === 'codex') {
headers['Authorization'] = `Bearer ${credential.apiKey}`;
} else {
headers['Authorization'] = `Bearer ${credential.apiKey}`;
}
} else if (credential.type === 'oauth' && credential.accessToken) {
headers['Authorization'] = `Bearer ${credential.accessToken}`;
} else if (credential.type === 'local' && credential.baseUrl) {
baseUrl = credential.baseUrl;
}
this._leases.delete(payload.leaseId); // ONE-SHOT consumption
return { ok: true, headers, baseUrl };
}Key properties:
- The materialized headers are returned exactly once. Calling
credential.materializewith the sameleaseIdagain returns{ ok: false, error: 'Lease not found or expired' }. - The lease is consumed regardless of HTTP success at the provider. Failed provider calls require a fresh lease.
- The materialize op is documented as "ONLY callable by trusted system actors (system.inference)." Today this is by convention; the framework does not enforce a caller allow-list. Auditing target state would add an explicit check.
Caller pattern
ts
// inside an inference adapter
const lease = await RequestReply.execute(this.context,
'system.factotum', 'credential.lease',
{ provider: 'anthropic', scope: 'infer' },
);
if (!lease.ok) throw new Error(`No credential: ${lease.error}`);
// hand the lease to a trusted system actor (here we're in one)
const materialized = await RequestReply.execute(this.context,
'system.factotum', 'credential.materialize',
{ leaseId: lease.leaseId },
);
if (!materialized.ok) throw new Error(`Materialize failed: ${materialized.error}`);
// now make the HTTPS call with materialized.headers
const res = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...materialized.headers },
body: JSON.stringify({ ... }),
});The raw apiKey / accessToken only exists inside the materialize result and only inside the calling actor's process memory. It does not travel on the bus, does not appear in logs, and does not get serialized into any other state.
Why two ops, not one
You could imagine a single credential.get-headers({ provider }) op. The two-op design has three reasons:
- Separation of concerns.
leasedecides whether a caller can use a credential (today: just "credential exists for this provider"; target state: capability checks).materializedecides how the credential gets formatted into HTTP headers. Two sets of code, two sets of reviewers. - Trust boundary in materialize.
materializeis documented as only-for-trusted-system-actors. A future enforcement pass adds the check there without affectingleasecallers. - Lease can outlive the lock window. A caller can hold a
leaseIdacross a longer pipeline, materializing only at the point of HTTP call. This makes the raw-key window minimal.
Lease scopes
Today, scope on a lease is recorded but not enforced. Defined values:
| Scope | Use |
|---|---|
infer | inference API calls |
admin | management operations |
read-only | listing / status only |
Target state would intersect these with capability tokens to decide which scopes a caller may request.
Failure modes
| Symptom | Cause |
|---|---|
credential.lease → { ok: false, error: 'No credential found for provider: X' } | Factotum has no row for provider X. The op also emits factotum.needkey { provider, requestedBy } so a UI can prompt the user. |
credential.materialize → { ok: false, error: 'Lease not found or expired' } | The lease was already consumed, expired, or never existed. |
credential.materialize → { ok: false, error: 'Credential no longer available' } | The credential row was deleted between lease and materialize. The lease is consumed. |
See also
- Factotum / secrets service — full op surface.
- Secret rotation — what happens during rotation.
- Authorization / Capability tokens — target-state caller authentication for materialize.
Source:
projects/matrix-3/packages/system-factotum/dist/index.js(onCredentialLeaseat lines 557-587,onCredentialMaterializeat lines 593-628, lease bookkeeping at 392-409 and 636-643).