PAM lines written into login and passwd as blocks, so login unlocks the keyring on both workstations; no daemon of its own; gcr's ssh agent named for the session until the environment can say a runtime-directory path. Go tools unlocked, lock, collections and ssh-keys, never reading a secret.
5.6 KiB
gnome-keyring
The secret service as a module (novox/hq ADR 0208, ADR 0102).
- Installs
gnome-keyring(it bringsgcr-4, whose ssh agent this uses),libsecret(the client library andsecret-tool) andseahorse(the keyrings' manager, for the operator). - Claims the mesh's
node-secret-serviceseat (no verbs yet, ADR 0208 §2). It requires no display: the secret service is a D-Bus service, and a Wayland session uses the same module. - Writes the PAM lines into the stacks, never over them (ADR 0102). Each is a marked block at the
end of the file; every other line stays the distribution's.
/etc/pam.d/login:auth optional pam_gnome_keyring.soandsession optional pam_gnome_keyring.so auto_start. The login manager's stack includeslogin, so the password typed at the login screen unlocks the login keyring, and the login session starts the daemon./etc/pam.d/passwd:password optional pam_gnome_keyring.so, so changing the account's password changes the keyring's, and the next login still unlocks it.
- Starts no daemon. PAM starts it at login, and D-Bus would if PAM had not.
- Names gcr's ssh agent socket for the session, in the
xinitrcslotfirst:SSH_AUTH_SOCKis$XDG_RUNTIME_DIR/gcr/ssh. The agent itself isgcr-ssh-agent.socket, a user unit the package enables by preset.
Tools
None reads a secret. They ask the Secret Service for names, counts and lock states, and the agent for fingerprints.
| tool | does |
|---|---|
gnome_keyring_unlocked |
the login and default keyrings, locked or not; whether the daemon runs |
gnome_keyring_lock |
lock a keyring now (login by default); unlocking stays the operator's |
gnome_keyring_collections |
every keyring: id, label, locked, item count, created, changed, default |
gnome_keyring_ssh_keys |
the agent's keys by fingerprint, size, type and comment |
What it improves on what was found
- The desktop's login unlocks the keyring. Its
/etc/pam.d/loginhad no keyring lines, so the keyring stayed locked after every login, and a script prompted for the password to unlock it. Both workstations now get the same lines. - One daemon. The session's start ran
gnome-keyring-daemon --starta second time, asking for an ssh component that gnome-keyring no longer has, and the window manager ran an unlock-prompt script. Both go. - The session has an ssh agent. The found
export SSH_AUTH_SOCKexported nothing: the second daemon printed no socket. The session's processes had no agent, although gcr's was listening.
The default keyring is not the login keyring
On both workstations, measured on 2026-10-04, the default keyring, where programs store new secrets,
is a second keyring, Default_keyring. The login keyring holds one item at most. PAM unlocks only the
login keyring. Another keyring opens with it only if its password is stored in the login keyring
("unlock automatically"). On the desktop the login keyring was locked and the default one unlocked,
which the unlock-prompt script did.
After the first login with this module: gnome_keyring_unlocked shows both. If the default keyring
is still locked, choose one, once, in seahorse:
- tick its unlock automatically when prompted;
- or move its items into the login keyring and make that the default.
Which keyring is the default is the operator's data, never the module's.
Blockers and a proposal
SSH_AUTH_SOCK belongs in the account's environment, and ADR 0203 cannot say it yet. The value
is a path under the account's runtime directory (/run/user/<uid>). ADR 0203 forbids $ in a
contributed value, and no ${machine:…} fact names that directory. So today the variable reaches
only the X session and what it starts, through the xinitrc slot. An ssh login, the login shell's
execute and the user manager's services do not get it.
Proposed: a machine fact ${machine:account-runtime-dir}, resolved like ${machine:account-home}
from the account's uid. The variable then becomes an environment contribution:
environment.variables.SSH_AUTH_SOCK=${machine:account-runtime-dir}/gcr/ssh
The slot contribution then goes. That is a progressive insight on ADR 0203, or a small record of its own. It changes the controller's machine facts, not this module's shape.
User-scoped units (mesh-host #72). gcr-ssh-agent.socket and gnome-keyring-daemon.socket are
enabled by the package's presets on both workstations, and nothing in the mesh asserts it. Once user
units ship, this module should declare both enabled.
What it leaves as found
- The keyrings themselves (
~/.local/share/keyrings/): the operator's data, never touched. ~/.config/i3/unlock-keyring.sh, the unlock-prompt script.
Migration (ADR 0182)
- On the laptop,
/etc/pam.d/loginalready has the two lines outside any block. After the first push they are there twice. Delete the two hand-written ones, outside the# BEGIN meshblock. - Once the
xorgmodule writes the session's start, delete from your own part of~/.xinitrctheeval $(/usr/bin/gnome-keyring-daemon --start …)line and theexport SSH_AUTH_SOCKafter it. - Once the
i3module carries the main configuration, itsexec … unlock-keyring.shline is gone. Delete~/.config/i3/unlock-keyring.sh. - On the desktop, log in again after the first push. The keyring is unlocked by the login from then on.
Blockers
node-secret-serviceand thexinitrcslot are ADR 0208's. Until the controller knows them,mctlreads them as unknown.- The environment fact above, and user-scoped units (mesh-host #72).