Access control
Passkeys and Google sign-in, roles scoped per area of Telark, and per-action deny rules such as "may edit plans but not approve them".
A tool that can freeze or roll back production needs finer control than "admin or not". The person who writes a freeze plan should not always be the one who approves it, and an auditor should see everything without changing anything.
What you get
- Sign-in with passkeys (WebAuthn) or Google single sign-on. No passwords.
- Roles that grant a level per area of Telark: applications, protection plans, insights, settings, users, groups, roles.
- Deny rules that withhold one action while keeping the level, for example Contributor on protection plans without the right to cancel them.
- Groups, so a role is assigned once to many people.
- Time-bound roles that expire on their own.
- Everything managed under Access & permissions in the dashboard and stored as Kubernetes resources in the release namespace.
How it works
Sign-in
Passkeys. A user registers a platform or security-key passkey and signs in with it. Who may register:
- a signed-in user, for their own account (to add another passkey);
- the holder of a one-time enrolment link, valid 10 minutes, created with
Add on another device or by an operator with
break-glass --enroll; - anyone with an email that has no account yet, only when
self-registration is on (
app.auth.passkey.selfRegistration="true", off by default). The new account gets the ReadOnly role.
Browsers offer passkeys only on https:// or http://localhost. Behind
an Ingress or Gateway, set app.auth.passkey.id and
app.auth.passkey.origin to the dashboard's public domain.
Google. An Admin turns it on under Settings with a Google client ID. The dashboard receives Google's ID token and the auth service checks its signature, audience, issuer, expiry, a single-use nonce and that Google verified the email. There is no client secret and no code exchange. The signing keys come from Google, or from a pinned key set when the cluster has no egress to Google. An unknown email gets a new account with the ReadOnly role; Google sign-in is not gated by the self-registration setting.
Sessions. A successful sign-in returns a session token: 32 random
bytes, valid 24 hours (SESSION_EXPIRY), with no sliding refresh. The
dashboard sends it only in the X-Session-Token header, never in a URL
or a cookie. Telark stores only its hash, as a Session resource named
session-<sha256>. Users list and revoke their sessions under
Settings.
First admin. List your email in app.auth.bootstrap.admins at
install. The chart refuses to render with the list empty and
self-registration off. A listed email receives the Admin role only from a
verified identity: its first Google sign-in, or a passkey enrolled with
kubectl exec -n telark deploy/telark-auth-service -- \
./main break-glass --email you@example.com --enrollthen opening /register?enroll=<token> within 10 minutes. Without
--enroll, the command promotes an existing account to Admin.
Roles
A role (AccessRole) is a list of entries, each a scope, a
level and optional deny rules:
scopesAndPermissions:
- scope: protection-plans
level: Contributor
rules:
- protection-plans.cancelprotectionplan.deny- Scopes:
applications,protection-plans,insights,settings,users,groups,roles, orALLfor every scope. - Levels:
ReadOnly<Contributor<Owner<Admin. A level covers every lower one. - Deny rules:
<scope>.<action>.deny. A deny rule from any role the user holds wins over every level, Admin included.
A user's grants are the roles assigned to them plus the roles of every group they belong to: the highest level per scope, and every deny rule. Only active users and active, unexpired roles count. Every service checks the caller's grants on every request; a hidden button in the dashboard is not the boundary.
Built-in roles
| Role | Grants |
|---|---|
| Admin | Admin on ALL: everything, including the Google sign-in settings. Only admins see other administrator accounts. |
| Owner | Owner on every scope: Contributor plus deletes, role and group assignments, plan approvals, and the analyzer settings. |
| Contributor | Contributor on every scope: create and edit plans, users, groups and roles, trigger rollbacks and syncs, analyze and triage insights, edit discovery and snapshot settings. |
| ReadOnly | ReadOnly on every scope: read everything, change nothing. |
The built-in roles carry no deny rules, are re-applied at every exporter start, and cannot be deleted or modified. New users get ReadOnly. There are no built-in groups.
Custom roles
Create roles under Access & permissions → Roles. Besides its scope entries, a role can carry:
- Validity:
permanent, ortemporarywithexpiresAtfor time-bound elevation. An expired role grants nothing. - Protection:
preventDeletion,preventModificationandpreventScopeChangesguard a role against accidental change. - Status: only
Activeroles grant anything.
A custom role gets nothing on a scope it does not list. A role that only
lists applications does not open the Insights page.
Guards
Route permissions decide who may call an endpoint; guards decide what the caller may change.
- Nobody hands out more than they hold: a role you author, assign to a user or attach to a group may not exceed your own level on any scope.
- Nobody changes their own roles, groups or status, or adds or removes themselves from a group.
- Administrator accounts are hidden from non-admins. Only a bootstrap admin may delete or suspend another administrator; bootstrap accounts cannot be deleted through the API, and nobody deletes their own account.
- Deleting a user ends their sessions immediately; every service refuses their calls from that moment. A user, group or role being deleted grants nothing.
- Two users cannot share an email address.
Insights
| Action | Needs |
|---|---|
| Open the Insights page | ReadOnly on insights |
| Analyze an application | Contributor on insights; insights.analyzeinsights.deny withholds it |
| Acknowledge, dismiss, reopen | Contributor on insights; insights.triageinsights.deny withholds it |
| Bulk triage in the dashboard | Owner on insights (each card is still checked as a single triage) |
| Model runtime status and live updates | ReadOnly on insights, or Owner on settings |
| Change the analyzer settings, validate or install a model | Owner on settings; settings.controlainsights.deny withholds it |
Settings
| Settings field | Needs |
|---|---|
| Excluded namespaces, dashboard refresh interval | Contributor on settings; editdiscoveryconfig |
| Snapshot retention | Contributor on settings; editsnapshotstorage |
| Analyzer | Owner on settings; controlainsights |
| Google sign-in | Admin on ALL; editoidcconfig |
Protection-plan actions and their levels are listed in Protection plans. The role editor offers every deny rule per area.
Limits
- Telark has no request rate limiting and no login lockout.
- Google is the only identity provider. There is no SAML or generic OIDC.
- Roles are per cluster. There is no delegated administration such as "may manage roles only for one team".
- The service token shared by Telark's services is equivalent to full
API access. Keep the
telark-service-token-secretSecret as tightly held as any cluster-admin credential.
Reference
Insights
Incident decision support. One card per affected workload with the likely cause, the evidence and the change it followed, plus a setup review of 60 rules. Local, read-only and optional.
Notifications
In-app notifications for the events that need a person, such as a finished rollback, an approval request or a role change.