Request Lifecycle
The following diagram shows the Orchestrator’s request processing pipeline for proxy apps. Each service extension hook is shown at the point where it executes in the flow. When a request arrives, the Orchestrator matches it against configured policies. For protected policies, the flow proceeds through authentication, attribute loading, authorization, header injection, optional upstream login, and request/response modification before the response is returned to the user. The authorization step evaluatesisAuthorizedSE if configured, along with any declarative authorization rules defined on the policy.
Policy decisions (authorization result and headers) are cached in the user’s session. On subsequent requests, cached decisions skip directly to the upstream login check, bypassing the authentication, attribute loading, authorization, and header building steps.
Hooks
isAuthenticatedSE
Determine whether the current user is already authenticated. Return true to skip the login flow, or false to send the user through authentication. Use this when you need custom logic to check authentication status — for example, validating an external session token or checking a cookie from another system.
Signature:
apps[].policies[].authentication.isAuthenticatedSE
Parameters:
| Parameter | Type | Description |
|---|---|---|
api | orchestrator.Orchestrator | Access to sessions, caches, secrets, logging, and other Orchestrator services |
rw | http.ResponseWriter | The HTTP response writer for the current request |
req | *http.Request | The incoming HTTP request |
bool — true if the user is authenticated, false otherwise.
Examples:
Build an IdP selector for multi-provider authentication
Build an IdP selector for multi-provider authentication
See the full example under
authenticateSE for a combined
implementation that uses both isAuthenticatedSE and authenticateSE to let
users choose which identity provider to authenticate with.Bridge HTTP Basic Auth to LDAP authentication
Bridge HTTP Basic Auth to LDAP authentication
See the full example under
authenticateSE for a combined
implementation that uses both isAuthenticatedSE and authenticateSE to
authenticate users against an LDAP directory over TLS.authenticateSE
Handle authentication when the user has not yet logged in. Use this to redirect to an external login page, validate credentials directly, or start a custom authentication flow.
Signature:
apps[].policies[].authentication.authenticateSE
Parameters:
| Parameter | Type | Description |
|---|---|---|
api | orchestrator.Orchestrator | Access to sessions, caches, secrets, logging, and other Orchestrator services |
rw | http.ResponseWriter | The HTTP response writer — use to redirect or return an error response |
req | *http.Request | The incoming HTTP request |
Build an IdP selector for multi-provider authentication
Build an IdP selector for multi-provider authentication
When multiple identity providers are available, you can give users a
choice of which one to authenticate with. This extension pairs
isAuthenticatedSE and authenticateSE to implement an IdP selector.
The IsAuthenticated function checks the session to determine if the user
has already authenticated with any configured IdP, while Authenticate
renders a selector form and delegates login to the chosen provider.- isAuthenticatedSE
- authenticateSE
- Configuration
idp-selector.go
Bridge HTTP Basic Auth to LDAP authentication
Bridge HTTP Basic Auth to LDAP authentication
When an application relies on HTTP Basic Auth, this extension intercepts
the credentials and authenticates the user against an LDAP directory over
TLS. The
IsAuthenticated function checks the session for a previous
successful bind, while Authenticate extracts the Basic Auth credentials,
connects to LDAP with StartTLS, and performs a bind to verify them.- isAuthenticatedSE
- authenticateSE
- Configuration
ldap-tls-auth.go
isAuthorizedSE
Decide whether an authenticated user is allowed to access the requested resource. Return true to allow the request or false to deny it. Use this to call an external policy engine, enforce attribute-based access control (ABAC), or apply custom business rules beyond what declarative authorization rules support.
Signature:
apps[].policies[].authorization.isAuthorizedSE
Parameters:
| Parameter | Type | Description |
|---|---|---|
api | orchestrator.Orchestrator | Access to sessions, caches, secrets, logging, and other Orchestrator services |
rw | http.ResponseWriter | The HTTP response writer for the current request |
req | *http.Request | The incoming HTTP request |
bool — true if the user is authorized, false otherwise.
handleUnauthorizedSE
Customize the response when a user fails authorization. Use this to redirect to a custom error page, return a specific error code, or log additional context about the denied request.
Signature:
apps[].handleUnauthorizedSE
Parameters:
| Parameter | Type | Description |
|---|---|---|
api | orchestrator.Orchestrator | Access to sessions, caches, secrets, logging, and other Orchestrator services |
rw | http.ResponseWriter | The HTTP response writer — use to write a custom error response or redirect |
req | *http.Request | The incoming HTTP request that was denied |
loadAttrsSE
Enrich the user’s session with additional attributes before the request is processed. Use this to pull in user details from external sources — such as an LDAP directory, a database, or a REST API — transform attribute values, or merge attributes from multiple identity providers.
Signature:
apps[].loadAttrsSE
Parameters:
| Parameter | Type | Description |
|---|---|---|
api | orchestrator.Orchestrator | Access to sessions, caches, secrets, logging, and other Orchestrator services |
rw | http.ResponseWriter | The HTTP response writer for the current request |
req | *http.Request | The incoming HTTP request |
error — return nil on success, or an error to indicate attribute loading failed.
Examples:
Load LDAP group memberships into the session
Load LDAP group memberships into the session
When authorization decisions depend on group memberships stored in an LDAP
directory, this extension queries LDAP for the authenticated user’s groups
and stores them in the session. Downstream hooks like
isAuthorizedSE or
createHeaderSE can then read the groups from the session without
repeating the LDAP lookup.- Extension
- Configuration
load-ldap-groups.go
createHeaderSE
Build custom HTTP headers to send to the upstream application along with the proxied request. Use this when header values need to be computed dynamically — for example, constructing a header from session attributes, looking up a value from an external service, or encoding user information for the upstream app.
Signature:
apps[].headers[].createHeaderSE
Parameters:
| Parameter | Type | Description |
|---|---|---|
api | orchestrator.Orchestrator | Access to sessions, caches, secrets, logging, and other Orchestrator services |
rw | http.ResponseWriter | The HTTP response writer for the current request |
req | *http.Request | The incoming HTTP request |
http.Header— a map of header names to values to inject into the upstream requesterror— returnnilon success, or an error if header creation fails
Build custom headers from session attributes
Build custom headers from session attributes
When an upstream application expects user identity in specific HTTP headers,
this extension reads attributes from the user’s session and constructs the
required headers. Each
createHeaderSE entry handles one header, allowing
you to transform or combine attribute values as needed.- Extension
- Configuration
create-headers.go
modifyRequestSE
Modify the HTTP request before it is forwarded to the upstream application. Use this to add authentication headers, rewrite paths, inject tracing headers, or transform the request body.
Signature:
apps[].modifyRequestSE
Parameters:
| Parameter | Type | Description |
|---|---|---|
api | orchestrator.Orchestrator | Access to sessions, caches, secrets, logging, and other Orchestrator services |
req | *http.Request | The outbound HTTP request to the upstream — modify this object directly |
This hook runs on every proxied request. Keep it lightweight to avoid adding latency. Use
api.Cache() to avoid repeating expensive lookups.modifyResponseSE
Modify the response from the upstream application before it reaches the user’s browser. Use this to add security headers, transform response content, adjust status codes, or inject additional content.
Signature:
apps[].modifyResponseSE
Parameters:
| Parameter | Type | Description |
|---|---|---|
api | orchestrator.Orchestrator | Access to sessions, caches, secrets, logging, and other Orchestrator services |
resp | *http.Response | The HTTP response from the upstream — modify this object directly |
This hook runs on every proxied response. Keep it lightweight to avoid adding latency. Use
api.Cache() to avoid repeating expensive lookups.Inject a single logout button into HTML pages
Inject a single logout button into HTML pages
isLoggedInSE
Check whether the user is already logged in to the upstream application. Return true if the upstream session is active, or false to trigger the login flow. Use this to inspect upstream cookies, session tokens, or other indicators of an active upstream session.
Signature:
apps[].upstreamLogin.isLoggedInSE
Parameters:
| Parameter | Type | Description |
|---|---|---|
api | orchestrator.Orchestrator | Access to sessions, caches, secrets, logging, and other Orchestrator services |
rw | http.ResponseWriter | The HTTP response writer for the current request |
req | *http.Request | The incoming HTTP request |
bool — true if the user is logged in to the upstream application, false otherwise.
loginSE
Perform the login to the upstream application. Use this to submit credentials to the upstream login page, exchange tokens, set upstream cookies, or perform any steps required to establish an upstream session.
Signature:
apps[].upstreamLogin.loginSE
Parameters:
| Parameter | Type | Description |
|---|---|---|
api | orchestrator.Orchestrator | Access to sessions, caches, secrets, logging, and other Orchestrator services |
rw | http.ResponseWriter | The HTTP response writer — use to set cookies or redirect |
req | *http.Request | The incoming HTTP request |
error — return nil on success, or an error if the upstream login fails.