Delegated Authentication
Delegated authentication lets a trusted service open a key-server session that acts as another principal, without holding that principal's credential. The service authenticates as itself, names the principal it is acting for, and every operation on the resulting session is authorized as that principal. Keys created on the session are owned by it.
The key server implements this in one module, DelegatedAuthentication (AM04). This
page describes what AM04 checks, which principals can be impersonated, and the client
contexts that drive it from C++ and Java. The REST Gateway exposes the same module as
POST /api/session/delegated; see
Integrating via the API for that path.
AM04 authenticates the delegator, not the target
The delegator is the TLS client certificate the connection presents. AM04 loads the certificate principal that certificate is enrolled as, and refuses the login unless:
- the delegator carries the
DELEGATIONflag (principal flag0x400). Without it the key server answers with an authentication error,Impersonation is not allowed for principal. Enrolling a certificate does not set the flag; an administrator sets it on the delegator's principal. - the delegator is not a remote engine. A host-group principal — which is what a remote engine authenticates as — cannot delegate (ADR-0112).
- the delegation cannot widen a privilege. Every operation the target holds must also
be held by the delegator. There is no exception for administrator roles: a target that
holds an operation the delegator lacks is refused with
Impersonation denied: target holds privileges the delegator lacks.
Because the delegator is a certificate, a delegated login always runs on a mutually authenticated TLS connection — the one connection type that presents a client certificate.
Who can be impersonated
The target set is closed. Exactly two kinds of principal can be named:
| Target | Named by | Principal class |
|---|---|---|
| A certificate principal | its DER-encoded certificate | TransportPrincipalInfo |
| An externally authenticated (XAuth) principal | its id | XAuthPrincipalInfo |
There is deliberately no way to impersonate a native password (SRP) principal. Delegation bypasses authentication, so a delegatable password identity would void the guarantee that principal type exists to provide (ADR-0029). An XAuth principal exists for exactly this purpose: it represents a user authenticated by a system outside the key server — your application's own sign-in — and is mapped into the key server only as a delegation target.
A certificate target is subject to the same validity and fitness checks a certificate login is (ADR-0108, ADR-0109); see Certificate Trust and Revocation.
A delegated session is re-evaluated on its delegator
A delegated session keeps a record of who delegated it and which certificate they presented. At the delegated session's next operation after any change that affects the delegator, the key server checks both again (ADR-0123):
- the delegator's principal still exists, is enabled, and still carries
DELEGATION; - the certificate the delegator presented is still enrolled and is not revoked.
If either check fails the operation is refused with a message that begins
delegator refused: principal <system>/<id> who delegated this session, followed by the
reason — for example is disabled, no longer carries DELEGATION, or presented a certificate that is no longer enrolled on the key server. Every later request on that
session is refused the same way. Disabling a service, clearing its flag, or revoking its
certificate therefore ends the sessions it delegated, not only its own.
Client contexts
C++ — TEDelegatedAuthenticationContext
TEDelegatedAuthenticationContext
(ADR-0126, header teauthdelegatedctx.h) carries the delegator's certificate and private
key and names one target:
setPKCS12(filename, password)orsetCredential(certChain, privateKey)— the delegator's credential;setX509Target(certificateDer)orsetXAuthTarget(principalId)— the target;authenticate()— returns the principal id the session acts as, which is the target's.
The context must be opened on a TEConnection::SSLMutualConnection. One target per
context: a second target call is refused with ERR_DELEGATION_TARGET_SET and the first
choice stands. The XAuth principal class is
TEXAuthPrincipalInfo.
Java — DelegatedAuthenticationContext
DelegatedAuthenticationContext
(ADR-0127, package com.eruces.teagent, authentication type
TEAuthenticationType.DELEGATED) takes the delegator's credential through setSecret(...)
— a PKCS#12 stream and password, or a KeyStore entry — and the target through
setX509Target(...) or setXAuthTarget(...). The target kind is the closed enum
DelegationTarget { NONE, X509, XAUTH }; no method accepts a selector string. It is
opened on a TEAgentSSLMConnection. A second target call throws
DELEGATION_TARGET_SET.
Other clients
The TypeScript agent drives AM04 as well, and the REST Gateway's delegated route is built on it. The C API does not expose delegated authentication.
Related pages
- Certificate Trust and Revocation — the checks a delegator's and a target's certificate pass.
- Key Server Architecture — where authentication sits in the request lifecycle.
POST /api/session/delegated— the Gateway route, its guard, and its refusal codes.