OXYGENHUB

Grant tokens reach hubs; unsetting core.sign works c96354484bd9

A home holding an agent's grant token and no hub token now offers the
grant as its credential for that hub, so a keyless agent's home needs
no other secret (the hub accepts grant tokens for fetch and push,
oxygenhub#241). `oxy config --unset core.sign` failed with "must be
change or seal": an empty value now means the default.

Refs oxygenhub#241
Author
Andy McCall @andymccall <[email protected]>
via
agent agent:claude@andymccall <[email protected]> · keyless, under your grant for changes,refs,seal · key bc42025c0ddb
When
· 2026-10-17 21:09 UTC
Signature
✔ signed by agent:claude@andymccall
Hash
c96354484bd96287c36037349c6bd02e0018bf790bfc04663f8c4efb894d0c13
Depends on
982864068a59 c895bc52e4e0 ff1f62fee654
Depended on by
nothing yet
In bookmarks
carried-not-removed doctor-trust identical-sides keyless-tags main merge-remote-bookmark paths-for-resolutions-and-amend push-notes show-stat subrepo-pin-state
In tags
v0.10.0 v0.11.0 v0.4.6 v0.5.0 v0.5.1 v0.6.0 v0.7.0 v0.8.0 v0.9.0
Edits
5 atoms, 0 tree operations, 2 files

Browse the tree at this change

modified crates/oxy-core/src/credentials.rs +19 −1
…
354 unchanged lines
355 355
            (None, None)
356 356
        } else {
357 357
            match self.get(&hub) {
358 -
                Ok(Some(e)) => (e.token, e.ca),
358 +
                // An agent's grant token serves when the home holds no
359 +
                // other: the hub takes it for the owner's repositories
360 +
                // (keyless agents, oxygenhub#241).
361 +
                Ok(Some(e)) => (
362 +
                    e.token
363 +
                        .or(e.grant)
364 +
                        .or_else(|| self.grant(&hub).ok().flatten()),
365 +
                    e.ca,
366 +
                ),
359 367
                Ok(None) => (None, None),
360 368
                Err(e) => {
361 369
                    warn_once(&format!("warning: credentials for {hub}: {e}"));
…
173 unchanged lines
535 543
            .save_grant("https://elsewhere.example", "oxyagent_h")
536 544
            .unwrap();
537 545
        assert!(store.get("https://elsewhere.example").unwrap().is_some());
546 +
        // The grant is the credential a remote there is reached with;
547 +
        // beside a hub token, the hub token is.
548 +
        assert_eq!(
549 +
            store.lookup("https://elsewhere.example/a/b").0.as_deref(),
550 +
            Some("oxyagent_h")
551 +
        );
552 +
        assert_eq!(
553 +
            store.lookup("https://oxygenhub.io/a/b").0.as_deref(),
554 +
            Some("oxyhub_t")
555 +
        );
538 556
        #[cfg(unix)]
539 557
        {
540 558
            use std::os::unix::fs::PermissionsExt;
…
125 unchanged lines
modified crates/oxy-core/src/repo/config.rs +2 −1
…
161 unchanged lines
162 162
            "core.sign" => {
163 163
                self.sign_changes = match value {
164 164
                    "change" => true,
165 -
                    "seal" => false,
165 +
                    // Empty: unset, the default.
166 +
                    "seal" | "" => false,
166 167
                    _ => return fail("core.sign must be \"change\" or \"seal\""),
167 168
                }
168 169
            }
…
178 unchanged lines