Quick start: Tenantry on your Teleport server in 10 minutes¶
This is the main path. Tenantry runs on the same server as your Teleport cluster, in Docker. One command starts a guided installer. It finds Teleport, creates what Tenantry needs in it, and asks you only five short groups of questions.
If your Teleport is on another server, or you have no Teleport yet, see Quick start variants.
Before you start¶
You need:
- A Linux server with Docker and Docker Compose v2, where Teleport already runs (in a Docker container, or as a local service with its
tctlbinary). - Root access (
sudo). The installer hands files to the users of the containers. - Teleport 18.x. The Tenantry image embeds
tctl18.11.1, which works with any 18.x cluster. For another major version see Install options. - A DNS name for Tenantry, for example
tenantry.acme.ch. - Decide how people will reach it (the wizard asks). The safe choices:
- Cloudflare Tunnel + Cloudflare Access: nothing is opened on your firewall. Recommended if you already use Cloudflare.
- Local network or VPN: the server itself serves HTTPS, with a publicly trusted certificate (TLS certificates).
- Your own reverse proxy or WAF.
Never expose Tenantry raw to the Internet
Tenantry holds a live Teleport identity and creates roles and tokens. A compromise is a compromise of your cluster. Always put a WAF, Cloudflare Access, a VPN or Teleport in front. See Exposure: never expose raw.
1. Get the installer¶
git clone https://github.com/Verttigo28/tenantry.git
cd tenantry
2. Run it¶
sudo scripts/install.sh
With no option, in a terminal, it starts the guided mode. (sudo scripts/install.sh --wizard does the same.) Press Enter to keep the [default]. Nothing is changed before the summary, and Ctrl-C quits.
Step 1/5: Teleport¶
The installer lists the Teleport it finds on this server, for example On this server: teleport (cluster teleport.acme.ch, Teleport 18.11.4). Choose it.
- It then asks whether to grant Tenantry's identity the full role. The default (No) is
--bot-role minimal: the Steward application and fleet listings, no right to create Teleport roles, join tokens or locks. Yes means--bot-role full(needed by "Add a proxy", the lock button and Tenantry-created roles). Creating roles amounts to cluster administration and a join token can enrol any agent: with the full role, a compromise of Tenantry is a compromise of the cluster. You can change it later by re-running with the other--bot-role. - It asks for the public address of the Teleport proxy, for example
teleport.acme.ch:443. Agents andtshuse it.
If nothing is detected, it asks for the name of the Teleport container (docker ps). If you answer "Elsewhere", see Quick start variants.
Step 2/5: Public name¶
The DNS name people open, and a short instance name (the Docker project becomes tenantry-<name>).
Step 3/5: Exposure¶
| Choice | What happens |
|---|---|
| Local network or VPN only | This server serves HTTPS itself (Caddy). You get step 4. |
| Behind my own reverse proxy or WAF | Tenantry listens on a private address and port; your proxy terminates TLS. You give the address, the address your proxy connects from (--trust-proxy, so the sign-in rate limit sees real client addresses; printed at the end for a proxy on this server) and the public URL. |
| Cloudflare Tunnel + Cloudflare Access | A cloudflared container opens an outbound tunnel. No port is published. You paste the tunnel token (typed hidden). |
Step 4/5: TLS certificate (local network or VPN only)¶
Because Teleport usually owns port 443, the wizard proposes another HTTPS port (9443) and the public URL becomes https://tenantry.acme.ch:9443.
- Reachable from the Internet on port 80? Answer yes for HTTP-01.
- Otherwise choose Let's Encrypt through DNS-01 and pick your DNS provider from the list (Infomaniak, OVHcloud, Cloudflare, Gandi LiveDNS, Hetzner, AWS Route 53, Azure DNS, deSEC, DigitalOcean, Linode/Akamai, PowerDNS, or any other acme.sh provider). It asks for the provider's settings and then the API credentials, typed hidden. See TLS certificates.
- Or give your own certificate files, your own ACME server, or (lab only) a self-signed certificate.
With a Cloudflare Tunnel or your own proxy this step is skipped: the certificate users see is served by Cloudflare or by your proxy.
Step 5/5: Administrator¶
A login name (default admin), optionally Teleport single sign-on (issuer, audience, allowed roles and, explicitly, the administrators' role, default tenantry-admin: see Teleport SSO), an installation directory (default /opt/tenantry) and the Tenantry release (default: the version of this checkout; build builds it locally). A strong password is generated and shown once at the end.
Summary and install¶
The installer prints the equivalent non-interactive command, with secrets as files at placeholder paths (/root/tenantry-dns.env, /root/tenantry-tunnel-token, /root/tenantry-bot-token). Answer y to install. The same command is printed again at the end: keep it for automation, after putting the secrets in those files (mode 0600).
What the installer does¶
With a local Teleport it uses that Teleport's own tctl, so there is no manual tctl step:
- Creates the Teleport roles
tenantry(minimal by default),steward-adminandsteward-helpdesk(the Steward console roles, so Tenantry never needs to create roles itself) and the Machine ID bottenantry. The role texts are part ofinstall.shitself and are sent totctlon stdin. - Writes the bot join token to a 0400 file, hands it to the
tbotcontainer, and deletes it after the first join. From then ontbotrenews a short-lived identity (1 hour, renewed every 20 minutes) that Tenantry reads. - Derives the rest from your Teleport: the auth address (
<container>:3025, pinned with the cluster CA pins), the Teleport version, the proxy address and, for a container, its Docker network. - Pulls the Tenantry release given with
--version(never an implicitlatest), pins it by digest and verifies its signature whencosignis installed (--require-signaturemakes that mandatory), generates the secrets (kept across re-runs), starts the containers and waits for health.
Everything lives in /opt/tenantry/<name> (compose project tenantry-<name>).
First sign-in¶
Open the public URL and sign in with the administrator login and the password printed at the end.
The Security page should show "Renewed by Machine ID". The Client proxies page should list your agents.
Equivalent command, written out
Guided mode answers like "this server, Cloudflare Tunnel" produce:
sudo scripts/install.sh --name tenantry --public-url https://tenantry.acme.ch \
--teleport-local docker:teleport --proxy teleport.acme.ch:443 \
--expose cloudflare-tunnel --tunnel-token-file /root/tenantry-tunnel-token --version <x.y.z>
And "this server, local network, DNS-01 (example provider: Cloudflare DNS)":
sudo scripts/install.sh --name tenantry --public-url https://tenantry.acme.ch:9443 \
--teleport-local docker:teleport --proxy teleport.acme.ch:443 \
--tls acme-dns --dns-provider dns_cf --dns-setting CF_Zone_ID=<zone-id> \
--dns-credentials-file /root/tenantry-dns.env --https-port 9443 --version <x.y.z>
If you chose Cloudflare Tunnel: finish in Cloudflare¶
At the end the installer prints the three steps. In short:
- Create the tunnel first (Cloudflare Zero Trust, Networks, Tunnels, Create a tunnel, cloudflared, Docker) and copy the token: the long string after
--token. - Access application first: Access, Applications, Add, Self-hosted. Domain = your Tenantry name. Policy Allow for your MSP team, with MFA, session 8 hours or less.
- Public hostname of the tunnel: your Tenantry name, service HTTP
tenantry:8443. - Bypass application for the two paths called by client servers without a browser:
tenantry.acme.ch/api/callbackandtenantry.acme.ch/api/i, policy Bypass (or Allow by the client sites' egress IPs). These endpoints answer only to one-time, unguessable ids.
Do the Access application before the public hostname: until it exists, the name is public. Details and the Teleport side: Exposure: never expose raw.
Next steps¶
- Add your first client: Onboard a client.
- Create technicians with a scope per client: Technicians.
- Add an alert channel (webhook, ntfy, Teams, Slack): Alerts.
- Read Security and the backup page.
Something failed? See Troubleshooting.