You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add an optional human-in-the-loop approval flow in which an external Telegram
bot presents a precise requested capability and an authorized person may deny
it or approve it once or through a bounded reusable rule.
Example prompt:
Is workload release-agent in workspace ws-123 allowed to run gh issue close 456 against github.com/acme/widgets?
Actions:
Deny
Allow once
Allow for this session
Always allow this exact operation
Always allow this bounded operation class (for example, GitHub Issues
operations for one tenant/persona/repository)
Architectural constraint
Telegram is an approval user interface, not part of Charon's credential data
plane and not a source of credential, endpoint, provider, item, hostname,
method, path, or secret-reference selection.
An external approval broker should:
receive a normalized capability request from the integrating control plane;
render only redacted identity and concrete operation information;
authenticate an allowlisted Telegram chat/user;
record the decision and any bounded reusable rule;
return a signed approval assertion to the workload-identity issuer; and
let the issuer mint Charon's existing short-lived, single-use manifest.
Charon should continue verifying manifests offline. It must not call Telegram or
wait on a chat interaction while holding an HTTP request or resolved secret.
Required decisions
Define the normalized approval-request schema and canonical request digest.
Decide whether approval assertions need their own key and schema or remain an
issuer-internal contract.
Define the exact predicates available to reusable rules:
tenant, persona, workload, and optionally workspace;
service and exact account/organization/repository resource;
named capability and operation class;
maximum duration, use count, and manifest TTL;
environment or risk tier.
Define an approval session as an issuer-authenticated tenant, persona,
workspace, and active lease tuple—not a Telegram chat session or a
workload-supplied identifier.
Bound session approval by the earliest of lease termination, workspace
disposal, explicit revocation, inactivity timeout, and configured maximum
duration.
Define which operations can never receive reusable approval.
Define rule creation, listing, expiry, revocation, and emergency disable.
Define behavior when Telegram or the approval broker is unavailable
(fail closed).
Decide how Telegram account recovery, bot-token rotation, and chat migration
affect authorization.
“Always” must never mean an unbounded natural-language match. A label such as
“anything relating to GitHub Issues” must compile to inspectable structured
predicates, such as one persona, one repository, a fixed set of issue
operations, and a bounded expiry.
Security requirements
Bind each prompt and callback to a random, single-use, expiring approval ID
and a digest of the complete normalized request.
Reject stale, replayed, edited, duplicated, or mismatched callbacks.
Use Telegram numeric user and chat IDs from an operator allowlist; do not
authorize by username or display name.
Ensure only the current pending message can mutate its decision; edit it to a
terminal redacted result after use.
Keep bot tokens, approval-signing keys, manifests, nonces, credentials,
provider references, and private resource data out of messages and logs.
Make deny and timeout the default.
Never let session approval survive lease replacement, workspace resume into a
new lease, persona reassignment, or approval-broker restart without durable,
revocable state.
Mint a fresh short-lived, single-use Charon manifest for every operation
covered by a session approval; the approval itself is never a reusable
Charon bearer token.
Require stronger confirmation for creating or widening reusable rules.
Prevent a workload from selecting or weakening the reusable-rule scope.
Preserve Charon's independent concrete destination/method/path enforcement;
human approval cannot override local deny-by-default policy.
Emit correlated, redacted audit records for request, delivery, decision,
rule match, issuer result, revocation, and timeout.
Rate-limit prompts and prevent approval-notification flooding.
Document Telegram as an external availability and account-takeover risk, not
as a secret store.
Suggested contracts
approval-request.schema.json
approval-decision.schema.json
approval-rule.schema.json
Optional OpenAPI for the approval broker's authenticated control-plane API
Telegram adapter behind an ApprovalChannel interface so other channels can
be added without changing decision semantics
The channel adapter should only deliver a presentation model and return an
opaque decision callback. Policy normalization and authorization belong in the
approval broker, not Telegram-specific code.
Acceptance criteria
ADR records trust boundaries, rule semantics, failure behavior, and
rejected alternatives.
Allow-once cannot be replayed and expires before or with the resulting
manifest.
Session approval is bound to one authenticated tenant/persona/workspace/
lease tuple and ends on lease termination, disposal, revocation,
inactivity timeout, or maximum duration.
Suspend/resume or lease replacement does not carry session approval into
the new lease.
Reusable rules are structured, inspectable, expiring, and revocable.
Goal
Add an optional human-in-the-loop approval flow in which an external Telegram
bot presents a precise requested capability and an authorized person may deny
it or approve it once or through a bounded reusable rule.
Example prompt:
Actions:
operations for one tenant/persona/repository)
Architectural constraint
Telegram is an approval user interface, not part of Charon's credential data
plane and not a source of credential, endpoint, provider, item, hostname,
method, path, or secret-reference selection.
An external approval broker should:
Charon should continue verifying manifests offline. It must not call Telegram or
wait on a chat interaction while holding an HTTP request or resolved secret.
Required decisions
issuer-internal contract.
workspace, and active lease tuple—not a Telegram chat session or a
workload-supplied identifier.
disposal, explicit revocation, inactivity timeout, and configured maximum
duration.
(fail closed).
affect authorization.
“Always” must never mean an unbounded natural-language match. A label such as
“anything relating to GitHub Issues” must compile to inspectable structured
predicates, such as one persona, one repository, a fixed set of issue
operations, and a bounded expiry.
Security requirements
and a digest of the complete normalized request.
authorize by username or display name.
terminal redacted result after use.
provider references, and private resource data out of messages and logs.
new lease, persona reassignment, or approval-broker restart without durable,
revocable state.
covered by a session approval; the approval itself is never a reusable
Charon bearer token.
human approval cannot override local deny-by-default policy.
rule match, issuer result, revocation, and timeout.
as a secret store.
Suggested contracts
approval-request.schema.jsonapproval-decision.schema.jsonapproval-rule.schema.jsonApprovalChannelinterface so other channels canbe added without changing decision semantics
The channel adapter should only deliver a presentation model and return an
opaque decision callback. Policy normalization and authorization belong in the
approval broker, not Telegram-specific code.
Acceptance criteria
rejected alternatives.
reusable approval, and bounded operation-class approval.
manifest.
lease tuple and ends on lease termination, disposal, revocation,
inactivity timeout, or maximum duration.
the new lease.
operation, edited callback, duplicate callback, and expired callback
attempts fail.
outage fail closed without interrupting already authorized unrelated
realms.
credentials, manifests, nonces, signing keys, provider references, or
private keys.
are updated.