Skip to content

Steward Integration

Steward is the separate web console for delegated Active Directory administration (one instance per customer). Operators sign in through Teleport Application Access: Teleport signs a JWT in the Teleport-Jwt-Assertion header, which the console validates. It also provides the helpdesk features (password reset, unlock) that replace the former JEA scenario.

The third wizard scenario, "Steward", automates the Teleport part of this setup.

What the integration automates

  • Creation of the two Teleport roles (steward-admin, steward-helpdesk);
  • registration of the Teleport application pointing at the console;
  • generation of the Tenantry's own role (the permissions needed to create the above);
  • generation of the app_service snippet for the agent, and of the console-side configuration (Authentication:Teleport block, as YAML and as environment variables);
  • end-to-end verification.

The steps in the console remain manual (see below).

Prerequisites

  • A Teleport cluster with Application Access, and an application agent (app_service service) that can reach the console over HTTPS.
  • Tenantry installed with valid tctl authentication (Install options), with tctl at the cluster version.
  • Steward deployed (HTTPS, with a certificate the Teleport agent can validate).
  • For passwordless step-up: a WebAuthn second factor enrolled by the operators (see troubleshooting f).

The "Steward" scenario (fields)

Field Purpose
Console URI How the Teleport agent reaches the console, e.g. https://steward.acme.internal:443. Normalized with an explicit port and a lowercase host: it is the JWT audience (aud), compared verbatim. A DNS name is preferable to an IP (which is absent from the certificate). A numeric host must be a real IPv4 address; a single-label host (e.g. https://steward:8443 on a Docker network) is accepted.
Proxy address Public Teleport proxy (host:port); used for JwksUrl and LaunchUrl.
Cluster name Read automatically via tctl status; it is the JWT issuer (iss).
Client Optional, picked from the client register on the first step (prefilled from ?client=<code> when you come from a client or console). Adds the label client_code: <code> to the application, so Teleport filters by client and the per-client role tenantry-client-<code> grants the application (see Technicians).
Application name Editable on the first step. Defaults to <client-code>-steward (e.g. demo-sa-steward) when a client is chosen, else steward; via a client proxy, <client-code>-steward or <instance name>-steward. Lowercase letters, digits, hyphens. Public address: <app>.<proxy host>.
Application description Editable; written to metadata.description (resource) and description: (app_service snippet). Defaults to Steward – <client name>, or Steward without a client. Values are YAML single-quoted (an apostrophe in a client name is doubled).
Roles steward-admin (full operators) and steward-helpdesk (restricted); the names must differ. Names reserved by Teleport are rejected (422): access, editor, auditor, admin, tenantry, member, requester, reviewer and the prefixes teleport-, bot-, preset-.
Per-session MFA (admin role) require_session_mfa: true, i.e. WebAuthn; required for passwordless step-up (TrustSessionMfa).
Fresh session (seconds) How long a Teleport session counts as "fresh" for step-up (30 to 3600, default 300).
Proxy CA file Optional: path, inside the console container, of the proxy's CA (JwksCaFile), if the proxy certificate is not public.

Default application label: app: steward (selected by the roles), plus client_code: <code> when a client is chosen. Applying never replaces an application of the same name that Tenantry did not create (tenantry-managed label): the apply is refused with would_overwrite and an explicit Replace it confirmation is required.

Generated files

File Contents Where to put it
teleport-roles.yaml The two roles (application access only). Applied by Tenantry (tctl create -f), or by hand.
tenantry-role.yaml Minimal tenantry role: rules role/app [list,read,create,update], app_server and cluster_auth_preference [list,read], plus the application's app_labels. See the security warning below. tctl create -f by an admin, then assign it to the identity Tenantry uses (tctl auth sign user or Machine ID bot). Useful when Teleport runs on another host.
teleport-app.yaml kind: app resource (dynamic registration). Applied by Tenantry.
teleport-app-service.snippet.yaml Static app_service block. teleport.yaml of the application agent (alternative, or in addition if the agent does not serve dynamic apps).
steward-teleport.yaml Authentication:Teleport block (Issuer, Audience, JwksUrl, JwksCaFile, TrustSessionMfa, StepUpMaxAge, LaunchUrl). config/steward.yaml of the console.
steward-teleport.env The same settings as STEWARD_Authentication__Teleport__* variables. .env / environment: of the console container.

The three buttons

  • Preview: validates the answers (422 error if invalid) and shows the six files. Nothing is applied.
  • Apply to Teleport: runs tctl create -f on the roles first, then the application. If the roles fail, the application is not attempted (step "skipped"). Idempotent on what the tool created: running it again updates (see "Overwrite protection"). After a success, the call waits up to 5 s for the application to become readable (Teleport auth cache); otherwise the response carries pending:true and you must run Verify again.
  • Verify: checks, in order:
  • role <admin> and role <helpdesk> present;
  • application <name> registered (reading tctl get app/<name>);
  • application service: an app service does serve this application;
  • URI identical to the expected URI;
  • application label matches the one the roles target.

Checks 3 to 5 are only performed if the application is registered.

Overwrite protection

Every role and application created by the tool carries the label tenantry-managed: 'true'. If a role or application with the same name already exists without this label, POST /api/steward/apply answers 409 {error:'would_overwrite', conflicts:[...]} and nothing is modified. The wizard then offers the "Replace existing" button (second confirmation), which resends the request with overwrite:true. Running Apply again on resources created by the tool is an update (idempotent), with no confirmation.

Tenantry role security

Warning. The right to create roles is the right to create any role, and therefore cluster administration. Use a short-lived identity (Machine ID, or tctl auth sign --ttl=...), protect the identity file and give it only to the Tenantry. This role covers only the Steward integration: the gateway scenarios (tokens, inventory, desktops) require additional rules. When the role allows proxy tokens (allowProxyToken), it carries token: list, read, create, delete: delete lets Tenantry revoke each token (tctl tokens rm) as soon as the proxy serves the console.

Manual steps in the console

  1. Open the console through Teleport (Teleport dashboard, or LaunchUrl).
  2. The first administrator is the Teleport user who completes the console's initial setup wizard.
  3. Delegations > Teleport: map the Teleport roles (steward-admin, steward-helpdesk) to the console roles.
  4. Enable "Teleport only" mode only after testing the connection.
  5. Emergency access (loss of Teleport access):
docker exec <container> dotnet Steward.Api.dll allow-password-login --confirm

Network rule

Only the Teleport agent should be able to reach the console's HTTPS port (firewall / Docker network). Otherwise, the JWT would no longer be the only way in.

Troubleshooting (observed in the lab, Teleport 18.2.0)

Symptom Cause Fix
a) access to app denied. User does not have permissions on the application Teleport refuses to create an application that the creator's roles do not allow: Tenantry role needs rules on role/app and app_labels matching the application's label. Apply tenantry-role.yaml and assign it to the identity used by Tenantry.
b) tctl apps ls does not show the newly registered application tctl apps ls only lists apps already served by an app service. Verification reads tctl get app/<name> and reports separately that no application service serves it (backend message: "no application service serves it"). Fix: app_service block from teleport-app-service.snippet.yaml on the agent, or resources with the application's label for dynamic registration.
c) Verify right after Apply fails Teleport's auth cache delays reads after a write. Apply waits up to 5 s (pending:true if the application is still not readable); run Verify again.
d) Protocol errors / tctl commands rejected tctl does not match the cluster version. Rebuild with --build-arg TELEPORT_VERSION= or install.sh --teleport-version X.Y.Z --build.
e) x509: certificate signed by unknown authority or proxy name not resolved Private CA in front of the proxy; name that the host's DNS does not resolve. install.sh --ca-file proxy-ca.pem (sets SSL_CERT_FILE for tctl); --add-host name:ip.
f) Step-up fails despite a second factor An OTP second factor cannot satisfy per-session MFA. Enroll a WebAuthn factor for the operators of the admin role.

Verified in the lab

  • Image built on the lab's Docker host, with tctl embedded (download verified by checksum).
  • Tenantry started with an identity file and a private CA against a Teleport 18.2.0 cluster.
  • Roles and application created; a second run updates them (no error, idempotent).
  • Verification result: roles present, application registered, URI and label correct; the "application service" check stays failing as long as no app service serves the application (expected behavior, see b).