How to connect to the gateway with the openshell snap¶
This guide connects the openshell CLI to a deployed gateway with an
OIDC client-credentials registration, a service account that needs no
browser. It suits automation and an administrator’s first session.
This guide does not cover a human operator’s interactive browser sign-in
(openshell gateway login). The only Hydra client a deployment registers
on its own is the gateway’s: a confidential authorization-code client,
created over the oauth relation, whose secret stays with the gateway. A
browser sign-in from the CLI needs a client of its own on Hydra.
Prerequisites¶
An active Charmed OpenShell deployment, for example from How to deploy Charmed OpenShell.
Juju CLI access to the model running the gateway, and to the model running the identity platform’s Hydra (the
iammodel, when deployed with theopenshell-stackTerraform module).A network path from this machine to the gateway’s
external_hostnameand to the identity platform’sidentity_hostname. The admin VM from the deploy guide has both, as does any instance on the Kubernetes VM’s network. A machine outside the MicroCloud reachesexternal_hostnameon the uplink, butidentity_hostnameonly if its network routes the Kubernetes network through that network’s OVN router.sudo, to add certificates to the host’s trust store, andjq.
The commands below run in the admin VM from the deploy guide.
Install the openshell snap¶
The CLI has to come from the same OpenShell release as the gateway; a newer CLI cannot decode its responses. Install the revision that Requirements and versions lists for your architecture, and hold it:
sudo snap install openshell --revision=1041
sudo snap refresh --hold openshell
On a machine that already has the snap, use
sudo snap refresh openshell --revision=1041 instead of the install.
Trust the gateway’s and the identity issuer’s certificates¶
The CLI dials two TLS endpoints: the gateway’s, and the OIDC issuer’s. Each
is signed by its own self-signed-certificates application unless your
deployment uses publicly trusted certificates. Fetch and install both CAs:
juju run self-signed-certificates/0 get-ca-certificate -m openshell --format=json \
| jq -r '.[].results."ca-certificate"' \
| sudo tee /usr/local/share/ca-certificates/openshell-gateway-ca.crt > /dev/null
juju run self-signed-certificates/0 get-ca-certificate -m core --format=json \
| jq -r '.[].results."ca-certificate"' \
| sudo tee /usr/local/share/ca-certificates/openshell-identity-ca.crt > /dev/null
sudo update-ca-certificates
Skip the core model command when the gateway and the identity issuer
share one certificate authority, or use a different model name if your
identity platform runs elsewhere.
Read the gateway’s OIDC configuration¶
juju run openshell-gateway-k8s/0 get-oidc-client-config -m openshell
Note the issuer and audience values from the result; both are needed
below. The issuer is https:// followed by the stack’s
identity_hostname. The result’s client-id is the gateway’s own
audience name, not a client you can authenticate as; the next step creates
that client.
Create an OAuth2 client on Hydra¶
Register a client-credentials client scoped to one of the gateway’s RBAC
roles. The Terraform modules name them openshell-admin and
openshell-user unless configured otherwise; juju config
openshell-gateway-k8s oidc-admin-role -m openshell shows yours.
grant-types, scope and audience take lists, so pass them in YAML
list syntax; a plain value fails the action’s validation with must be of
type array:
juju run hydra/0 create-oauth-client -m iam --format=json \
name=openshell-cli \
'grant-types=[client_credentials]' \
'scope=[openshell-admin]' \
'audience=[openshell-cli]' \
token-endpoint-auth-method=client_secret_post \
> openshell-cli-client.json
Replace openshell-admin with openshell-user for a non-admin
principal, openshell-cli in audience with the audience read
above, and iam with the model your Hydra unit runs in. The result holds a
client-id and a client-secret. Hydra does not show the secret again,
so keep the file, and keep it private:
chmod 600 openshell-cli-client.json
jq -r '.[].results."client-id"' openshell-cli-client.json
Hydra places a client-credentials client’s granted scopes in the token’s
scp claim, never in groups. The gateway’s oidc-roles-claim
config defaults to groups, which suits a human’s browser login but
not this service-account path. The deploy guide sets
openshell.oidc.roles_claim = "scp"; on a deployment that did not, run
juju config openshell-gateway-k8s oidc-roles-claim=scp -m openshell
before the principal you register here can pass the gateway’s RBAC
checks, for example to create a sandbox.
Register the gateway with the CLI¶
The gateway listens on port 8443, behind Traefik in TLS passthrough. Name
the port: without it the CLI reaches Traefik’s HTTPS router on port 443,
which answers 404 Not Found, and openshell status reports
invalid compression flag.
export OPENSHELL_OIDC_CLIENT_SECRET="$(jq -r '.[].results."client-secret"' openshell-cli-client.json)"
openshell gateway add https://<external-hostname>:8443 \
--name production \
--oidc-issuer <issuer-url> \
--oidc-client-id <client-id> \
--oidc-audience openshell-cli \
--oidc-scopes openshell-admin
Replace <external-hostname>, <issuer-url> and <client-id> with
the values from the previous steps, and openshell-admin with the scope
you granted.
The CLI does not renew the token on its own. When a command fails with
invalid token: ExpiredSignature, request a new one with
OPENSHELL_OIDC_CLIENT_SECRET still set:
openshell gateway login production
Verify the connection¶
openshell status -g production
Expect Status: Connected, Authentication: Authenticated (OIDC) and a
Version that matches openshell --version.
Create a first sandbox¶
openshell -g production sandbox create --name first
openshell -g production sandbox list
openshell -g production sandbox exec -n first -- id
openshell -g production sandbox delete first
The driver pulls the default sandbox image and converts it into an LXD image
as soon as it starts, which takes several minutes; a create issued before
that finishes waits for it. Once it is ready, a create takes seconds. A
sandbox from another image takes minutes the first time that image is
used. The sandbox lists as Ready once its supervisor
has registered with the gateway over external_hostname, and it shows up
as an LXD instance in the gateway’s project, as a MicroCloud member lists:
lxc list --project openshell
Remove the registration¶
openshell gateway remove production