Skip to content

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

  1. Create the profile file ~/.config/szenera/profile.json ($XDG_CONFIG_HOME is 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
        }
      }
    }
    
  2. Enter the base URL under services. The * entry applies to everything without its own entry and is enough today. The address must begin with http:// or https://, and a trailing slash is removed.

  3. Choose the credential under credential. The type api-key with a value ak_… under key is the standard way. The other two types are described under “Options”.

  4. Decide on readOnly. true blocks every command that changes something before a single network packet is created, so keep it for a production profile. If the setting is missing, true applies.

  5. Set default to 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.

  6. 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 whoami shows the ID, email, name, Organization, and the number of roles (route GET /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.