Users, roles and API tokens
hawkBit keeps its users in a configuration file. Qawk keeps them in the database, managed from the console and shared by every instance — so adding a person does not mean a deployment.
Who can sign in
Three kinds of credential, checked in this order:
- The administrator, from the environment.
QAWK_ADMIN_USER/QAWK_ADMIN_PASSWORD, with every permission. It is never stored in the database and always works — which is how a brand-new server is set up, and how a lost password is fixed by a restart. It is also why the password must not be left atadmin. - An API token.
qawk_and 48 hex digits, sent asAuthorization: Bearer <token>or as the password of basic authentication (curl -u alice:qawk_…), for tools that only speak that. Only its SHA-256 is stored; the token itself is shown once, when it is made. Expiry is optional.
A token acts with its owner's permissions at the time of use. Take a role away from someone and their tokens lose it in the same moment — there is no separate list of token scopes to remember to revoke. - A user in the database.
A password (PBKDF2-SHA256, 600,000 iterations) and any number of roles. A disabled user cannot sign in.
Why signing in takes half a second. The password hash is deliberately expensive, and the console sends credentials with every request. So a successful check is remembered for thirty seconds. Any change to a user, role or token forgets them all at once on the instance that made the change; other instances catch up within the same thirty seconds.
Roles
A role is a named set of hawkBit's own permissions. Every route keeps the permission hawkBit gives it, so a role means the same thing here as it would there.
Four roles are built in and rewritten at every start, so they cannot drift:
| Role | May | May not |
|---|---|---|
admin | Everything, including users, roles and the audit log. | — |
operator | Targets, channels, software, rollouts. The daily job. | Delete anything, change server configuration, approve a release. |
release-manager | An operator who also approves releases and can force a gate. | Manage users and roles. |
viewer | Read everything. | Change anything. |
Make your own from any set of permissions. Deleting a role takes it away from
whoever had it. SYSTEM_ADMIN is the permission that manages users and
roles and reads the audit log.
curl -u admin:$PW $Q/qawk/v1/permissions # every permission there is
curl -u admin:$PW -X POST -H 'Content-Type: application/json' \
-d '{"name": "centre-manager", "description": "moves centres between channels",
"permissions": ["READ_TARGET", "UPDATE_TARGET"]}' $Q/qawk/v1/roles
Separate who ships from who approves. Four-eyes approval only means
something if the two people are different — and Qawk enforces that a release
cannot be approved by whoever asked for it. Give operators operator
and keep release-manager for the people who sign things off.
API tokens
For CI and scripts. Console: My account → new API token.
curl -u rm-1:$PW -H 'Content-Type: application/json' \
-d '{"name": "ci", "expiresInDays": 90}' $Q/qawk/v1/tokens
curl -H "Authorization: Bearer qawk_…" "$Q/rest/v1/targets?limit=1"
Give a token an expiry unless you have a reason not to. A token with no expiry outlives the job it was made for, and usually the person too.
The audit log
Every request that changes something is recorded: method, path, result,
user, how they signed in, and their address — the first
X-Forwarded-For behind a proxy. So is every refused sign-in.
Reads are not recorded, on purpose: a console refreshing every two seconds would bury everything that matters under itself.
curl -u admin:$PW "$Q/qawk/v1/audit?all=true&limit=50"
curl -u admin:$PW "$Q/qawk/v1/audit?q=user==alice;status=ge=400"
It is filtered like any hawkBit list, on user, via,
method, path, status, address
and at. It is kept for QAWK_AUDIT_DAYS — 180 by default,
0 for ever — and pruned hourly.
What it is good for
- Who forced that gate, and why. Forcing requires a written reason, and the reason is in the release's history as well as here.
- Who assigned a set to a device in a frozen channel. A freeze stops the pipeline, not a person with the permission — and this is where that shows up.
- Whether someone is guessing passwords. Refused sign-ins, with addresses.
The audit log is not tamper-proof. It is a table in the same database as
everything else, and anyone who can reach that database can change it. If you need
evidence rather than a record, ship it out — /metrics and the
OpenTelemetry export are the hooks for that.
In the console
Users and roles and Audit log appear for those with
SYSTEM_ADMIN. My account — password and tokens — is there for
everyone. The header shows who you are signed in as, with your roles.
API
Who am I, create a user, create a role, create a token, the audit log.