Repository navigation
identity.gpg: generate the sandbox's gpg.conf from the host's - #696
Merged
Merged
Conversation
The sandbox gpg client ran on compiled-in defaults, so a host that tightened digest/cipher preferences, weak-digest, compliance or the trust model signed, encrypted and verified by stricter rules than gpg inside (invariant 7). gpgconf --list-options gpg lists none of the preference options (gpg 2.5.24), so snug reads the files: <sysconfdir>/gpg.conf, and the first of gpg.conf-<version>..gpg.conf in the host GNUPGHOME, as gpg does. Each is rewritten from an allowlist of crypto/trust options, aliases and compliance shortcuts mapped to the carried spelling, system meta commands carried, into two generated files so gpg inside applies its own precedence. An allowlisted line snug cannot carry refuses the run. Refs #689 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…me drops under -v Two pieces from the parallel #689 implementation (kept on feat/689-gpg-conf-files): - A profile grant at ~/.gnupg/gpg.conf was displaced by the generated file. Two authors, one path: refuse when the host user file carries anything; with nothing carried the stub stays and no user file is generated. A grant at ~/.gnupg/gpg.conf-* is refused always: gpg reads the versioned name instead of the generated file. - Options left behind are named under -v, keyword only, never value (GENERATED-CONFIG.md §6a). policy.GPGConfSummary. Refs #689 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…; disable dirmngr Red team round on the merged #689 branch (gpg 2.5.24): - F1/F2 sev:medium. Aliases and compliance shortcuts were rewritten to the canonical option. gpg's [force] locks one option-table entry, and a shortcut is a different entry: system `[force] openpgp` + user `compliance gnupg` gave AES256/SHA-256 on the host, 3DES/SHA-1 in the sandbox. no-pgp2/6/7/8 (set compliance back to gnupg) were dropped. Now every alias and shortcut is carried as written. - F3 sev:low. Host no-auto-key-locate dropped; gpg's default did a WKD lookup through a dirmngr it started inside. The keyring is read-only, so no lookup can import: the user file always ends in disable-dirmngr. - F4/F5 sev:low. throw-keyids (keyid 0000000000000000 on host, real ID inside) and compression choices (no compressed packet on host, algo=2 inside) dropped. Carried, with disable-signer-uid. - F6 sev:low. assert-signer and trusted-key also take a FILE name (`assert-signer signers.txt` read ./signers.txt). Key IDs only now. Tests: TestGPGConfKeepsTheHostsSpelling, TestGPGConfCarriesWhatAMessageLeaks, TestGPGConfKeyIDOptionsRefuseAFileName, TestGPGConfUserFileDisablesDirmngr, TestIdentityGPGHidesWhatTheHostHides (dirmngr assertion fails with the line removed: dirmngr=1). Refs #689 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #689.
Sandbox gpg client ran on compiled-in defaults; host tightening of digest/cipher prefs, weak-digest, compliance, trust, key-ID hiding, compression lost (invariant 7).
Premise correction (measured, gpg 2.5.24)
gpgconf --list-options gpglists none of the preference options, so no probe of effective values, no "write in full". gpgconf also ignoresgpg.conf-<version>, which gpg itself reads. Details in issue comment.What
gpgconf --list-dirs(homedir, sysconfdir) +gpg --version. Reads<sysconfdir>/gpg.confand the first existing of<homedir>/gpg.conf-<version>…gpg.conf-<major>,gpg.conf, as gpg does (viainternal/hostread). Unreadable / FIFO / failed probe → refuse.policy.GPGConfOptionsinto a generated read-only file: system one at the host sysconfdir path, user one at~/.gnupg/gpg.conf. gpg inside applies its own precedence; system meta commands ([force],[ignore],[ignore-all],[user NAME]) carried.personal-cipher-prefs,openpgp,no-pgp6, …) carried AS WRITTEN:[force]locks one option-table entry, rewriting changed what it overrides.throw-keyids,disable-signer-uid, compression options.assert-signer,trusted-key: hex key IDs only (gpg also reads a file name there).disable-dirmngr: keyring inside is read-only, a WKD/keyserver lookup can only leak the address.~/.gnupg/gpg.confwhen host user file carries anything, any grant at~/.gnupg/gpg.conf-*.-v, keyword only, never value.docs/src/identity.md"Your gpg.conf", held byTestBookListsExactlyTheCarriedGPGConfOptions.Two parallel implementations of #689 merged here; the other is kept off-branch.
Red team (three rounds, all fixed)
\r \v \fwhitespace: CRLFrequire-compliancedropped silently.personal-cipher-prefs AES128dropped → AES256 inside;gnupgaftercompliance openpgpdropped → 3DES/SHA-1 inside.[force] openpgp+ usercompliance gnupg: host AES256/SHA-256, sandbox 3DES/SHA-1.no-pgp2/6/7/8dropped.no-auto-key-locatedropped → WKD lookup via dirmngr started inside.throw-keyidsdropped (host keyid 0000000000000000, sandbox real ID).compress-algo nonedropped (sandboxcompressed packet: algo=2).assert-signer signers.txtread ./signers.txt.Tests
TestGPGConf*,TestProbeGPGConf*,TestStageGPGConf*, goldeninternal/policy/testdata/gpgconf-*.txt, gpg bwrap/filesystem goldens.TestIdentityGPGCarriesHostGPGConf(sign digest algo 8, AES128 via alias, host--no-optionscontrol),TestIdentityGPGRefusesAnUncarriableGPGConf,TestIdentityGPGHidesWhatTheHostHides(keyid 0000000000000000, no compressed packet, no dirmngr; dirmngr assertion fails withdisable-dirmngrremoved:dirmngr=1).make gategreen.make verify: 5 passed, 4 skipped, 0 failed.make integrationlocally (SNUG_TEST_NET=1,SNUG_SANDBOX_TIMEOUT=25m): sandbox suite all pass exceptTestDoctorRunsCleanOnAHostThatCanRunSnug,TestOfflineHasOnlyLoopback—ip_greloaded, gre0/gretap0/erspan0 in every netns, fails on any branch. 61 engine tests, floor 46. Default 8m sandbox / 4m hostless suite timeouts exceeded on this host (podman 6.1.2, engine tests 10–17s each); no test failed.🤖 Generated with Claude Code