Just-In-Time Credential Leases
Long-lived secrets handed to automation are a standing liability. CredentialBroker
applies zero standing privilege: a consumer takes a short-lived lease — a
token bound to a secret name with an expiry — and the real value is fetched only
at redeem() time, only while the lease is valid, through a pluggable
resolver (an unlocked SecretManager’s get, an environment lookup, a
vault client). Expired or revoked leases yield nothing.
Secret values never enter executor/MCP records: the executor and MCP surfaces
manage the lease lifecycle only. redeem(), which returns the real value,
is a deliberate Python-API-only escape hatch for code that must handle the
secret. The module is pure standard library and imports no PySide6; the
clock and resolver are injectable, so expiry is deterministically testable.
Headless API
from je_auto_control import CredentialBroker
broker = CredentialBroker(resolver=secret_manager.get) # resolver(name)->value
token = broker.lease("db_password", ttl=120) # token, not the value
if broker.is_valid(token):
password = broker.redeem(token) # fetched just in time, Python-only
connect(password)
broker.revoke(token) # or let it expire after ttl seconds
active() lists non-expired leases as {token, name, ttl_remaining} with no
values. A module-level default_broker backs the executor/MCP commands;
configure its resolver once with set_secret_resolver(fn).
Executor commands
Command |
Effect |
|---|---|
|
Issue a lease for |
|
Report |
|
Revoke a lease token; |
|
List active leases (no secret values). |
There is intentionally no redeem command on the executor, MCP, or Script
Builder surfaces — exposing the value there would leak it into run records.
Redeeming is Python-only. The same lifecycle operations are exposed as MCP tools
(ac_lease_secret / ac_lease_valid / ac_revoke_lease /
ac_lease_active) and as Script Builder commands under Tools.