A session from an inherited pipe: GIT_REMOTE_PDS_SESSION_FD (lichen's GIT-REMOTE-PDS-IMPROVEMENTS G1, due by PER-SITE-PROCESS P4). Rust: yes. Interface: one new environment variable; nothing else changes.
Why. lichen pushes for a site's owner with a session it already holds, and today passes it in PDS_ACCESS_TOKEN / PDS_DID / PDS_DPOP_KEY. Any process of the same user can read another's environment (/proc/<pid>/environ), so a script or a terminal command running beside the push in the same site could read the owner's token. With this, the caller writes the session to a pipe and names its read end; nothing about it is in the environment.
What (6dd56a79, on main f1cf329; from the fork notplants-bot.bsky.social/git-remote-pds-fork):
src/session_fd.rs:take_from_env()runs first thing inmain. WhenGIT_REMOTE_PDS_SESSION_FDnames a descriptor (never 0–2), it callsprctl(PR_SET_DUMPABLE, 0)first, then reads the pipe to its end and closes it. It keeps one JSON session:did,pds,access_token,dpop_key(nullable),expires_at(nullable).- An error is final: the caller named a pipe, so nothing falls back to another credential.
- Linux only; elsewhere the variable is refused.
PipedSession'sDebugnever shows the token or the key.
auth::resolve_auth: the piped session is the only credential used, ahead of thePDS_*variables and the storedauth loginones.remote_helper::resolve_pds_url: the piped session's PDS is the one asked, and the remote URL's handle must resolve to the session's DID, or the push is refused before any write.- Unchanged: with the variable unset, everything is as before (the
PDS_*variables, then the stored credentials). - Also:
libcas a Linux-only dependency (already in the lock graph), and a README section.
Tests:
- unit (
session_fd):- the session is read and the descriptor is closed, also when the pipe holds no session;
- a descriptor of 0–2 or garbage is refused;
- the session never appears in
Debug.
- integration (
tests/session_fd_tests.rs, throughgitand the fake PDS, which now records each write'sAuthorizationand answersresolveHandle):- the push:
- without the variable and with nothing stored, the push is not logged in and writes nothing;
- with a stored credential, it pushes with that credential (
auth loginstill works); - with the variable, every write carries the piped token, the stored credential notwithstanding;
- another account: a session for another account is refused before any write;
- unreadable helper: a helper that has read a session has
/proc/<pid>/environ,/memand/fdrefused to the same user (EACCES), against a control helper without a session whose environment is readable.
- the push:
Evidence (lichen-ci, uid 1000):
cargo fmt --checkclean.cargo clippy --all-targets: the same 9 warnings asf1cf329, all pre-existing, none added; the only line moved isauth.rs's redundant closure, by this change's 16 lines.cargo test: lib 40 passed (2 ignored, as before), main 15, bundle 5, fetch 5, push_state 2, push 3, remote_helper 1, session_fd 3.- plants, each red at its assertion:
- the process left dumpable:
the_process_that_read_the_session_cannot_be_read_by_another; - the descriptor left open: both
session_fdread tests; - a stored credential ahead of the piped session:
a_push_takes_its_session_from_the_pipe; - another account's session accepted:
a_session_for_another_account_is_refused.
- the process left dumpable:
The lichen side follows once this is merged and the submodule pin moves: the site process writes the pipe and passes its read end to that one git command, and PSP-CRED-ENV1 closes.