Registry access keys
Deployed and supported. The fields and commands described here are stable within version v1alpha1.
A registry access key (RegistryAccessKey) is a registry machine credential, limited to
named repositories and to the actions pull and/or push. It is used where your sng
session is not available: above all so that your App resources pull the images of your
private repositories and, if you allow it, so that an application of your tenant (a CI job
for example) pushes images.
Prerequisites
- A tenant session (
sng tenant use acme) and thedeploy:writeright (policyreadwrite). - At least one declared repository (Repositories and retention).
1. Declare an access key
apiVersion: registry.stackngo.io/v1alpha1
kind: RegistryAccessKey
metadata:
name: puller
spec:
repositories: [web, api] # names of repositories of the tenant, or "*" for all
actions: [pull] # pull and/or push; never delete
rotateEveryDays: 90 # new secret every 90 days; 0 or absent = never
sng apply infra/RegistryAccessKey/puller.yml
To start from a template: sng template gen RegistryAccessKey puller > puller.yml.
What you get
A few moments after the apply, the platform prepares for this key a registry credential
named <key>-registry (here puller-registry, or the name given in spec.secretName). Its
username is accesskey/acme/puller; its password is generated by the platform and never
appears in your manifests.
2. Pull the images of an App
This is the main use: name the credential in imagePullSecrets.
apiVersion: deploy.stackngo.io/v1alpha1
kind: App
metadata:
name: shop
spec:
imagePullSecrets: [puller-registry]
services:
api:
image: ovh-gra-0.registry.dev.stackngo.fr/acme/api:1.4.2
ports: ["8080"]
sng apply infra/App/shop.yml
sng app describe shop
The credential is updated automatically at each renewal: your App resources have nothing to
change. For this use, a pull-only key is enough and limits exposure.
3. Use the key in an application (ci: true)
By default, the credentials of a key only serve image pulls (imagePullSecrets): an
App that names them in its environment variables (env or envFrom) is refused at apply
time. To let an application of the tenant read them, for example a CI job that pushes
images, declare the key with ci: true:
apiVersion: registry.stackngo.io/v1alpha1
kind: RegistryAccessKey
metadata:
name: builder
spec:
repositories: [web]
actions: [pull, push]
ci: true # credentials readable in environment variables
rotateEveryDays: 30
apiVersion: deploy.stackngo.io/v1alpha1
kind: App
metadata:
name: builder
spec:
services:
build:
kind: job
image: ovh-gra-0.registry.dev.stackngo.fr/acme/builder:1.0.0
env:
REGISTRY_USERNAME: { secret: builder-registry, key: username }
REGISTRY_PASSWORD: { secret: builder-registry, key: password }
Keep ci: true for the keys that need it: a key readable by an application can be copied
by it, whereas a pull-only key never leaves the platform.
4. Read the credentials from the CLI
For a tool that cannot open a tenant session, a tenant administrator reads the current credentials of a key:
sng registry access-key credentials builder # username only
sng registry access-key credentials builder --show-password # with the password
The password changes at each renewal: a copy (a CI variable, for example) must be updated after each rotation. For a CI outside the platform, prefer the job's OIDC session: no secret to store, no renewal to track. See Build and push images from CI.
5. Renewal
With rotateEveryDays: N, the platform generates a new secret N days after the previous
renewal and updates the <key>-registry credential. The old secret remains
accepted for graceHours hours (24 h by default): pulls in progress finish without error. Your App resources
see nothing: their next pull uses the new secret.
To obtain a new secret without waiting for the deadline, renew the key on demand, from the console (Renouveler le secret in the list of keys) or with the CLI:
sng registry access-key rotate puller
sng registry access-key credentials puller --show-password
The old secret remains accepted during the key's grace period (graceHours, 24 h by default):
update the copies (a CI variable, for example) during that time. Only the previous secret stays
accepted: renewing twice in a row ends the grace period of the older one. This renewal is reserved for tenant administrators. The default pull key is
managed by the platform and cannot be renewed on demand.
To cut access right away, with no grace period, delete the key
(sng kind delete RegistryAccessKey puller) then reapply it. The old secret is refused as soon
as it is deleted; pulls by the App resources that use it fail until the new credential is
ready.
Verification
sng app describe shop
The service switches to Ready: the image was pulled with the key. An image from a repository outside
spec.repositories is refused.
What you can expect
- What a key cannot do: delete an image (
deleteis reserved for sessions), access the repositories of another tenant, or access an undeclared repository even with"*". - No policy to write: a key is not evaluated by your policies; its rights are
exactly
spec.repositories×spec.actions. In return, any member who hasdeploy:writecan declare apushkey: grant this right accordingly. - Pull-only by default: without
ci: true, no application reads the key's credentials. - Revocation: deleting the key's manifest makes its secret unusable within a few
seconds, and removes the
<key>-registrycredential. - Username: always
accesskey/<tenant>/<name>.
Common errors
| Symptom | Cause | Fix |
|---|---|---|
sng apply refuses metadata : seul name est permis (…) | The manifest carries a label or an annotation | Remove it; see the alternatives above |
sng apply refuses a delete action | spec.actions only accepts pull and push | Delete with a session (sng registry delete) |
sng apply refuses an App that names <key>-registry in env or envFrom | The key does not have ci: true | Add ci: true to the key, or use the credential in imagePullSecrets only |
App pending ImagePullSecretNotFound | The key has just been applied, or imagePullSecrets does not carry <key>-registry | Wait a few moments; check the name (spec.secretName if given) |
App still pending ImagePullSecretNotFound | Another credential already carries this name | Choose another spec.secretName |