Profiles and credentials
Create a profile with an environment, a credential type, and write protection, either as a file or with environment variables only, and check it with whoami.
5 minute readCLIUpdated: 10/25/2026
On this page
Before you start
- For
- Anyone pointing the CLI at an environment for the first time or working with several environments side by side
- Prerequisite
- the built CLI, the base URL of your environment, and an API key
ak_…(the standard way) or an account with a password - Where
- command line
After this guide, the CLI knows your environment, your credential, and the write protection, as a profile in a file or through environment variables only, and szenera whoami shows which account and organization it talks to.
A profile bundles two things: the credential and the mapping from service to base URL. Everything a command needs to know about the other end is stored there and nowhere else. Every profile belongs to one organization.
Steps
-
Create the profile file
~/.config/szenera/profile.json($XDG_CONFIG_HOMEis respected if it is set). Its structure:{ "default": "staging", "profiles": { "staging": { "services": { "*": "https://<basis-adresse-ihrer-umgebung>" }, "credential": { "kind": "api-key", "key": "ak_…" }, "readOnly": false }, "prod": { "services": { "*": "https://<basis-adresse-der-produktion>" }, "credential": { "kind": "api-key", "key": "ak_…" }, "readOnly": true } } } -
Enter the base URL under
services. The*entry applies to everything without its own entry and is enough today. The address must begin withhttp://orhttps://, and a trailing slash is removed. -
Choose the credential under
credential. The typeapi-keywith a valueak_…underkeyis the standard way. The other two types are described under “Options”. -
Decide on
readOnly.trueblocks every command that changes something before a single network packet is created, so keep it for a production profile. If the setting is missing,trueapplies. -
Set
defaultto the profile that should apply without--profile=. If the file holds exactly one profile, that one applies even without a default. If it holds several without a default, the CLI aborts and names them. -
Check the profile:
szenera whoami szenera whoami --profile=prod --json
Options
Without a file: environment variables
Environment variables sit above the file: every variable that is set replaces the matching value of the chosen profile. SZENERA_BASE_URL and SZENERA_API_KEY alone carry a complete profile, with no file at all. It is then named environment and is not write-protected.
| Variable | Effect |
|---|---|
SZENERA_PROFILE |
Which profile of the file applies. --profile=<name> takes precedence |
SZENERA_BASE_URL |
Sets the * entry under services |
SZENERA_API_KEY |
API key. Replaces the profile’s credential |
SZENERA_OUTPUT |
json or table. --json and --table take precedence |
SZENERA_PROFILE_FILE |
Path of the profile file. Takes precedence over any search |
SZENERA_BASE_URL="https://<basis-adresse>" SZENERA_API_KEY="ak_…" szenera device list
Where the CLI looks
The first hit wins:
| Location | When |
|---|---|
$SZENERA_PROFILE_FILE |
explicitly named |
~/.config/szenera/profile.json |
otherwise. $XDG_CONFIG_HOME is respected |
Credential types
api-key: the standard way. The key travels as Authorization: Bearer with every call and does not expire after a quarter of an hour, so the CLI needs neither a cache nor a refresh for it. A value without a prefix that the API recognizes as a key is rejected before a network packet is created, as soon as a command needs the credential (exit 2). --help and health run even with a wrong value.
password: for the person at the computer. The profile carries email and password and, with two-factor sign-in, additionally totpSecret (Base32). The CLI computes the one-time code itself. The access token is then stored with permissions 0600 next to the configuration (.szenera-token-<profil>.json), is discarded one minute before it expires, and is renewed before every call if it will not last until the next round trip, even in the middle of a command that waits for minutes. If the account belongs to several organizations, the sign-in aborts instead of guessing.
{ "credential": { "kind": "password", "email": "…", "password": "…", "totpSecret": "…" } }
none: public routes only. szenera health runs with it. Every other command aborts with a note that the profile carries no credential.
Services per domain
Instead of *, an entry under services may name a platform domain (such as fleet or composition) and give it its own address. * remains for the rest. A name that is not a domain is rejected when the file is read, so a typo does not silently fall back to *.
Check the result
szenera whoamishows the ID, email, name, Organization, and the number of roles (routeGET /v1/me).- If a different organization appears than the one you expected, the profile points somewhere other than you intended. It is not the key that is wrong, but the choice.
If something goes wrong
| Symptom | Meaning | Solution |
|---|---|---|
Keine Konfiguration gefunden — die Kommandozeile weiß nicht, mit welcher Umgebung sie sprechen soll. (no configuration found) (exit 2) |
Neither a file at one of the two locations nor SZENERA_BASE_URL. |
Create the file or set the two variables. |
Unbekanntes Profil „…". … führt: dev, prod. (unknown profile) (exit 2) |
--profile= or SZENERA_PROFILE names a profile the file does not know. |
Choose one of the names listed. |
… ist im Profil „prod" gesperrt — das Profil ist schreibgeschützt. (blocked, the profile is write-protected) (exit 2) |
A command that changes something meets a write-protected profile, or one without the setting. | Set readOnly: false if the profile may write. |
… „audience" muss „tenant" sein. (audience must be tenant) (exit 2) |
The file holds a profile for platform operations. szenera does not know it. |
Remove the profile from the file or name a separate file through SZENERA_PROFILE_FILE. |
Kein API-Schlüssel: erwartet wird ein Wert mit dem Präfix … (not an API key) (exit 2) |
The value in the profile or in SZENERA_API_KEY is not a key. |
Take the plaintext from the portal. See Create an API key. |
… braucht einen Ausweis, das Profil „…" trägt keinen. (needs a credential, the profile has none) (exit 1) |
The profile has no credential or has kind: "none". |
Add SZENERA_API_KEY=ak_… or set credential in the profile. |
| HTTP 401 with exit 3 | The key is not valid: revoked, expired, or the profile points to a different environment than the key. | Check each profile with szenera whoami --profile=<name>. See JSON output and exit codes. |
… gehört zu mehreren Organisationen … (belongs to several organizations) |
Password sign-in with an account that is in several organizations. | Use an API key of the organization you want. |