Secrets - kubed-io/selenium-flow GitHub Wiki
A secret is a named set of keys โ nextcloud with username and password,
say โ that an operator put on the server. A caller can use one and can never
see one. No tool, resource or report returns a value.
That is the whole point. A password an agent holds is in its transcript, its tool call, and whatever its host logs. A password it merely names is in none of them.
Set SECRETS_DIRS to a directory โ or several, separated like PATH. Inside,
one directory per secret and one file per key, which is exactly the shape
Kubernetes mounts a Secret in:
/secrets/
โโโ nextcloud/
โโโ username
โโโ password
โโโ .meta.yaml # optional
The file name is the key and the file's contents are the value. .meta.yaml
describes the secret without changing it:
description: Admin login for the homelab Nextcloud
allowed_urls:
- https://nextcloud.example.comUnset SECRETS_DIRS means the feature is off, and secret://secrets says so rather
than returning an empty list that looks like an empty catalogue.
The secret://secrets resource returns names, keys and sites. Never values.
| Field | Means |
|---|---|
keys |
what may be named as key
|
allowed_urls |
the only sites it may be typed on, as exact origins |
restricted: false |
no sites declared: usable anywhere |
allowed_urls_rejected |
its site list is broken, so it cannot be used at all until an operator fixes it |
Give write a secret instead of text:
write(css="#password", secret={"name": "nextcloud", "key": "password"})
The result carries "text_from": "secret" and no value. The same argument goes
in a flow step's args โ see Flows โ where the step's line in the
report reads text=<hidden>.
Five rules, each refused rather than guessed at:
-
Only
writetakes a secret, and the rule is structural rather than written down: no other action has asecretargument, so there is nowhere to put one. It is the action that types a value into a field and does nothing else with it. -
A secret is never part of a string. Flow parameters are written
${name}into any argument; a secret is not, and could not be. So no flow can send one somewhere by writing it into a URL or a script โ a secret reaches exactly one place, the field it is typed into.That is not the same as the value being safe once typed, and the difference is worth knowing. A
writewithsubmit: truecan land the browser on?q=<what was typed>, which is why the server scrubs a typed secret out of every report and error and refuses to store that page as somewhere to return to. See What this does not protect. -
A secret's name may not come from a parameter.
secret: {name: ${which}}is refused: choosing which credential gets typed is not a decision a caller's parameters may make. -
Never
textas well. Two values, one field, and picking one would be a guess that is wrong silently. -
Navigate first, in its own step. A
writebinding a secret may not also take aurl, because the site check reads the page the browser is on at the moment of typing โ awritethat navigated would be checked against the page it was leaving.
A restricted secret is typed only when the browser is on one of its
allowed_urls, compared as an exact origin: scheme, host and port.
https://nextcloud.example.com.evil.test is not a match, and neither is plain
http://. A refusal names the page the browser was on and the sites it would
have accepted.
The config file's secrets.entries is a second source, merged over what
secrets.dirs collects โ not a replacement. It can add a description or a
leash to a directory's secret, add or replace one of its keys, or define a
whole secret with no directory behind it at all. See
Configuration for the file itself.
| Field | If the config sets it | If it does not |
|---|---|---|
description |
replaces the directory's | the directory's, if any |
allowed_urls |
replaces the directory's leash entirely, a broken line included | the directory's leash, if any |
keys |
added; a key with the same name as a directory file replaces it for this key | the directory's keys |
A key reference is exactly one of three kinds:
keys:
password: {file: /run/secrets/nextcloud/password}keys:
token: {env: AUTH_TOKEN}keys:
username: {value: demo}The value is read at the moment it is bound, never cached: an env: key reads
the environment then, a file: key reads the file then.
The Secrets tab shows three warnings:
-
inline valueโ one of the secret's keys is{value: โฆ}, written into the config file itself rather than read from somewhere else. -
key unresolvedโ an{env: โฆ}variable is unset, or a{file: โฆ}is missing, right now. The secret stays in the catalogue โ Kubernetes projects secrets asynchronously โ and binding that key refuses with the reason. -
a broken leash โ a directory's
_allowed_urlsfile has a line that does not parse as a bare origin. The secret cannot be used anywhere until it is fixed. A config-declaredallowed_urlscannot end up here: an unparseable line there stops the server at boot instead.
Prefer file: or env:; value: writes the secret into the config file
itself.
A parameter is for what varies between runs; a secret is for what must not be seen. An email address is a parameter. Its password is a secret.
Flows ยท write ยท Deployment