Interlaken

The interlaken CLI

A small command that holds your credentials, keeps a token fresh, and makes authenticated calls.

interlaken does the token dance so you do not have to. It authenticates as an API client, caches the token, refreshes it when it expires, and gives you a curl that already knows the base URL and the Authorization header.

It has no interactive sign-in. The credential is always an API client, which is the right shape for a tool that lives in a terminal and in CI alike.

Signing in

Each profile is one zone. --api is that zone's host, not a shared endpoint.

interlaken login \
  --api https://api.eu-par-1.interlaken.ai \
  --client-id "$INTERLAKEN_CLIENT_ID" \
  --client-secret "$INTERLAKEN_CLIENT_SECRET"

The command proves the credentials with a real token request before saving anything, so a typo fails here rather than on your next call.

The commands

login    --api URL --client-id ID --client-secret SECRET [--profile NAME]
token    [--profile NAME]                  print a valid bearer token
api      [--profile NAME] METHOD PATH [-d BODY|@file] [-H 'K: V']...
whoami   [--profile NAME]
profiles                                   list saved profiles
logout   [--profile NAME]                  revoke the token, forget the secret

Making calls

interlaken api GET /api/v1/vms
interlaken api GET "/api/v1/vms?status=running&limit=100"
interlaken api POST /api/v1/vms -d '{"name":"web-1", …}'
interlaken api POST /api/v1/vms -d @vm.json
interlaken api DELETE /api/v1/vms/0f7c1e1e-…

-d @file reads the body from a file, which saves fighting your shell over quoting. -H adds a header and can be repeated. The response goes to stdout as JSON, so jq works as you would expect:

interlaken api GET /api/v1/vms | jq -r '.items[] | "\(.id)  \(.name)  \(.status)"'

Borrowing the token

curl -s https://api.eu-par-1.interlaken.ai/api/v1/vms \
  -H "Authorization: Bearer $(interlaken token)"

token prints a valid bearer, fetching a new one first if the cached one has expired. Useful when you want the CLI's credential handling and something else's HTTP client.

Profiles, one per zone

A profile pairs one zone with one API client. Since zones are separate deployments, addressing two of them means two profiles, and an API client is per zone as well:

interlaken login --profile paris --api https://api.eu-par-1.interlaken.ai --client-id --client-secret
interlaken login --profile dev   --api https://api.dev.example            --client-id --client-secret

interlaken --profile dev api GET /api/v1/vms
interlaken profiles
interlaken whoami

whoami prints the profile, the zone and the client. It is worth running before anything destructive, because the only thing separating your development zone from production is a flag you might have forgotten.

Environment variables

VariableReplaces
INTERLAKEN_API--api
INTERLAKEN_CLIENT_ID--client-id
INTERLAKEN_CLIENT_SECRET--client-secret
INTERLAKEN_PROFILE--profile

In CI, set the three credential variables from your secret store and call interlaken api directly. There is no need to login first if the environment already carries everything.

Where state lives

$XDG_CONFIG_HOME/interlaken/config.json, or ~/.config/interlaken/config.json. The file is created 0600 in a 0700 directory.

The client secret is stored in that file in the clear, because it is the credential: there is nothing to encrypt it with that would not itself have to be stored beside it. Treat the file as you would an SSH private key. On a shared or ephemeral machine, prefer the environment variables and never run login.

Signing out

interlaken logout --profile dev

This revokes the current token at the server and then deletes the profile, so the credential stops working immediately rather than when it would have expired.

On this page