Skip to content

Console, CLI and access

The console and the CLI use the same JSON API (reference), so they share authentication, roles and the audit log.

Roles

Role Can
viewer See targets, backups, diffs, change summaries, restores and sandboxes.
operator + back up now, verify now, pause and resume, restore to a sandbox, query and manage sandboxes, read the audit log.
restorer + restore to a new database or a download.
restorer-admin + restore in place, pin and unpin backups.

Roles map from emails and Cloudflare Access groups in the chart:

auth:
  provider: cloudflare-access
  roles:
    viewer: ["*@example.com"]
    operator: ["group:sre"]
    restorer: [alice@example.com]
    restorer-admin: [bob@example.com]
  scopes:                               # optional: limit someone to some orgs or projects
    contractor@example.com: { orgs: [acme] }

Tenax verifies the Cf-Access-Jwt-Assertion JWT (team domain and audience) on every request, so a request that bypasses the tunnel is rejected. When Tenax publishes the console (below) it finds the team domain and the audience itself; for an Access application you manage, set auth.cloudflareAccess.teamDomain and audience. With auth.provider: none (local development only) every request gets auth.devRole.

Reaching the console

There are two ways in, and they can be used together:

  • For people without cluster access: a public address behind a login. Set a hostname and Tenax publishes the console there through its Cloudflare tunnel: an Access application that lets in the same people as the sandbox routes (expose.cloudflare.allowEmails / allowGroups), a DNS record and a route to tenax-api. People open https://tenax.example.com in a browser, or run tenax login --server https://tenax.example.com once, and log in with their email; they never need a kubeconfig. Their role comes from auth.roles.

    auth:
      provider: cloudflare-access
      roles: { viewer: ["*@example.com"], restorer: [alice@example.com] }
    expose:
      provider: cloudflare
      cloudflare: { zone: example.com, apiTokenSecret: tenax-cloudflare-api, allowEmails: ["*@example.com"] }
      cloudflared: { enabled: true, consoleHostname: tenax.example.com }
    

    The controller keeps the route in place and stores the application's team domain and audience in the Secret tenax-console-access, which tenax-api reads; until it exists the console answers "console login not ready". To read the team domain, the API token needs Access: Organizations, Identity Providers, and Groups: Read; without it Tenax reads it from the console's login redirect, or set auth.cloudflareAccess.teamDomain.

  • For people with cluster access: tenax console. It forwards a local port to the console through your kubeconfig and opens it in your browser. It keeps running until Ctrl+C; from another terminal, the other commands use it with export TENAX_SERVER=http://127.0.0.1:8080. With auth.provider: cloudflare-access the forward needs no Access login: it reaches a port tenax-api serves only on 127.0.0.1 inside its pod, which only kubectl port-forward can reach, so Kubernetes RBAC (pods/portforward in Tenax's namespace) decides who gets in, with the role auth.portForwardRole (default restorer-admin; empty turns the port off).

The CLI

Installing it and connecting it: Install the CLI. All commands: CLI reference.

The audit log

Every write (backup now, restore, pin, sandbox changes) and every query is recorded with the user, role, target, outcome and source address, in tenax-api's structured logs and on the console's Audit page.