Skip to content

[arbiter-authentication/2.10.2] Portable source custody and versioned codecs - #78

Open
omry wants to merge 1 commit into
pr76from
pr77
Open

omry wants to merge 1 commit into
pr76from
pr77

Conversation

@omry

@omry omry commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

Load portable identity evidence only from complete enrolled custody using the existing native publisher and complete result validator. Add bounded strict v2 private/public codecs for executable Go/Python peers, preserving exact v1 advertisement reconstruction and historical receipt validation. Public registration and CLI selection remain on the current fresh flow until target-side support is complete.

Validation: explicit140-fileBlack;38focused tests; isolated Python1833passed/43skipped; lint/type; complete Go tests and vet. Current primary general, configured DBB and fresh independent history-aware general reviews passed with zero unresolved findings.


… codecs

Load portable identity evidence only from complete enrolled custody using the existing native publisher and complete result validator. Add bounded strict v2 private/public codecs for executable Go/Python peers, preserving exact v1 advertisement reconstruction and historical receipt validation. Public registration and CLI selection remain on the current fresh flow until target-side support is complete.

Validation: explicit140-fileBlack;38focused tests; isolated Python1833passed/43skipped; lint/type; complete Go tests and vet. Current primary general, configured DBB and fresh independent history-aware general reviews passed with zero unresolved findings.
@omry
omry changed the base branch from main to pr76 October 30, 2026 14:01
@omry
omry added this pull request to stack #77 October 30, 2026 14:01
@gitar-bot

gitar-bot Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Code Review 👍 Approved with suggestions 0 closed / 1 findings

🟡 Medium risk · The v2 codecs and enrolled-identity reuse could misbind a portable credential to a new enrollment if custody or certificate bindings are mishandled.

Portable identity provisioning now loads evidence only from complete enrolled custody and adds bounded strict v2 private/public codecs for Go/Python peers, while preserving v1 advertisement reconstruction and historical receipt validation. One minor open suggestion: the same-server check in NewProvisionalFromIdentity (client/go-cli/internal/identity/portable.go) compares raw URL strings, so equivalent spellings like https://SOURCE.invalid:443 can bypass it; comparing a normalized origin or the bound server ID would close the gap.

💡 Edge Case: Same-server check compares raw URL strings, easy to bypass

📄 client/go-cli/internal/identity/portable.go:98-103

NewProvisionalFromIdentity refuses to reuse a source identity on the same server with source.serverURL == serverURL, which is an exact string comparison. validateProvisionalMetadata accepts any https URL that has a host, so https://source.invalid/, https://SOURCE.invalid or https://source.invalid:443 all point at the source server but pass this check. The guard tested by same target accepted therefore holds only when the URL is spelled exactly the same way. Fix: compare a normalized origin (lowercased scheme and host, default port removed, path ignored), or better, compare against the source's bound server ID when the target server ID is known.

Compare normalized origins instead of raw strings, and fail closed if either URL doesn't parse.
func sameOrigin(a, b string) bool {
	ua, ea := url.Parse(a)
	ub, eb := url.Parse(b)
	if ea != nil || eb != nil {
		return true
	}
	port := func(u *url.URL) string { if p := u.Port(); p != "" { return p }; return "443" }
	return strings.EqualFold(ua.Scheme, ub.Scheme) && strings.EqualFold(ua.Hostname(), ub.Hostname()) && port(ua) == port(ub)
}
🤖 Prompt for agents
Code Review: Portable identity provisioning now loads evidence only from complete enrolled custody and adds bounded strict v2 private/public codecs for Go/Python peers, while preserving v1 advertisement reconstruction and historical receipt validation. One minor open suggestion: the same-server check in `NewProvisionalFromIdentity` (`client/go-cli/internal/identity/portable.go`) compares raw URL strings, so equivalent spellings like `https://SOURCE.invalid:443` can bypass it; comparing a normalized origin or the bound server ID would close the gap.

1. 💡 Edge Case: Same-server check compares raw URL strings, easy to bypass
   Files: client/go-cli/internal/identity/portable.go:98-103

   `NewProvisionalFromIdentity` refuses to reuse a source identity on the same server with `source.serverURL == serverURL`, which is an exact string comparison. `validateProvisionalMetadata` accepts any https URL that has a host, so `https://source.invalid/`, `https://SOURCE.invalid` or `https://source.invalid:443` all point at the source server but pass this check. The guard tested by `same target accepted` therefore holds only when the URL is spelled exactly the same way. Fix: compare a normalized origin (lowercased scheme and host, default port removed, path ignored), or better, compare against the source's bound server ID when the target server ID is known.

   Fix (Compare normalized origins instead of raw strings, and fail closed if either URL doesn't parse.):
   func sameOrigin(a, b string) bool {
   	ua, ea := url.Parse(a)
   	ub, eb := url.Parse(b)
   	if ea != nil || eb != nil {
   		return true
   	}
   	port := func(u *url.URL) string { if p := u.Port(); p != "" { return p }; return "443" }
   	return strings.EqualFold(ua.Scheme, ub.Scheme) && strings.EqualFold(ua.Hostname(), ub.Hostname()) && port(ua) == port(ub)
   }

Verification

Rules No rules evaluated

Functional validation Not enabled

Set up

For more verification details, comment gitar display:verbose.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing compact verification results.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source

Comment on lines +98 to +103
func NewProvisionalFromIdentity(serverURL, name string, now time.Time, source *PortableIdentity) (*Provisional, PairingSecret, error) {
if source != nil {
raw, _ := json.Marshal(source.source)
if _, err := decodePortableSource(raw, source.key, &now); err != nil || source.serverURL == serverURL {
return nil, PairingSecret{}, errProvisional
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Edge Case: Same-server check compares raw URL strings, easy to bypass

NewProvisionalFromIdentity refuses to reuse a source identity on the same server with source.serverURL == serverURL, which is an exact string comparison. validateProvisionalMetadata accepts any https URL that has a host, so https://source.invalid/, https://SOURCE.invalid or https://source.invalid:443 all point at the source server but pass this check. The guard tested by same target accepted therefore holds only when the URL is spelled exactly the same way. Fix: compare a normalized origin (lowercased scheme and host, default port removed, path ignored), or better, compare against the source's bound server ID when the target server ID is known.

Compare normalized origins instead of raw strings, and fail closed if either URL doesn't parse.:

func sameOrigin(a, b string) bool {
	ua, ea := url.Parse(a)
	ub, eb := url.Parse(b)
	if ea != nil || eb != nil {
		return true
	}
	port := func(u *url.URL) string { if p := u.Port(); p != "" { return p }; return "443" }
	return strings.EqualFold(ua.Scheme, ub.Scheme) && strings.EqualFold(ua.Hostname(), ub.Hostname()) && port(ua) == port(ub)
}
  • Apply fix

Check the box to apply the fix or reply for a change | Was this helpful? React with 👍 / 👎

@omry

omry commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner Author

PR-cycle state — maintained automatically. Do not edit by hand.

Mechanical PR-cycle state (JSON)
{
  "approval": {
    "candidate_revision_fingerprint": "sha256:813b237516a66c51ac26d5fca7bdb2ae592d67147235c4caea0a602e3d603f60",
    "evidence": {
      "attestations": [],
      "candidate_revision_fingerprint": "sha256:813b237516a66c51ac26d5fca7bdb2ae592d67147235c4caea0a602e3d603f60",
      "check_conclusions": [
        {
          "conclusion": "SUCCESS",
          "name": "Gitar",
          "run_id": 124105161373
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform Linux arm64",
          "run_id": 124105158191
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform Linux x64",
          "run_id": 124105158583
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform Windows arm64",
          "run_id": 124105158069
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform Windows x64",
          "run_id": 124105158231
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform macOS arm64",
          "run_id": 124105158030
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform macOS x64",
          "run_id": 124105158475
        },
        {
          "conclusion": "SUCCESS",
          "name": "Python 3.10",
          "run_id": 124105158044
        },
        {
          "conclusion": "SUCCESS",
          "name": "Python 3.11",
          "run_id": 124105158262
        },
        {
          "conclusion": "SUCCESS",
          "name": "Python 3.12",
          "run_id": 124105158184
        },
        {
          "conclusion": "SUCCESS",
          "name": "Python 3.14",
          "run_id": 124105158041
        },
        {
          "conclusion": "SUCCESS",
          "name": "Python lint",
          "run_id": 124105157927
        },
        {
          "conclusion": "SUCCESS",
          "name": "Website",
          "run_id": 124105157541
        }
      ],
      "delivery_deferral_ledger_digest": "sha256:4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
      "finding_dispositions_digest": "sha256:4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
      "operation_identity": "sha256:98a899b2991cc5e80751924aa73ef8a9391db840e086735645773dc2e239f6b3",
      "review_request": {
        "body_digest": "sha256:a3005e3624873e256560f2496279ae552e56f43c6fc318ebb82bff02a9195ae1",
        "id": 6524915052
      },
      "review_result": {
        "body_digest": "sha256:8d0025ee1f1e2a3d2e39a33301cc19d2d07aa6c624f3301612e28df4a2ca4eee",
        "id": 6524939849
      },
      "security_review": {
        "context_identity": "sha256:a4429dd789609ced9ac087fc8453beef90d1c5b8192a85c7129b1a95910285f4",
        "proof_identity": "sha256:441c7f486ad2ecf0271df573b6ff8379164d4c5ea08a542400fa2698baf4047a",
        "requested": "dbb",
        "schema_version": 1
      }
    },
    "evidence_fingerprint": "sha256:d469d2682e753aa6ac4d1c3302b0defdcf85a9116f16f6ddc1e57b720874dc51",
    "head_sha": "42decb66262591759a645ee8c1a9be799aaac03c",
    "operation_identity": "sha256:98a899b2991cc5e80751924aa73ef8a9391db840e086735645773dc2e239f6b3",
    "review_request_id": 6524915052,
    "review_result_id": 6524939849,
    "status": "approved-evidence-recorded"
  },
  "candidate_revision_fingerprint": "sha256:813b237516a66c51ac26d5fca7bdb2ae592d67147235c4caea0a602e3d603f60",
  "check_conclusions": [
    {
      "conclusion": "SUCCESS",
      "name": "Gitar",
      "run_id": 124105161373
    },
    {
      "conclusion": "SUCCESS",
      "name": "Platform Linux arm64",
      "run_id": 124105158191
    },
    {
      "conclusion": "SUCCESS",
      "name": "Platform Linux x64",
      "run_id": 124105158583
    },
    {
      "conclusion": "SUCCESS",
      "name": "Platform Windows arm64",
      "run_id": 124105158069
    },
    {
      "conclusion": "SUCCESS",
      "name": "Platform Windows x64",
      "run_id": 124105158231
    },
    {
      "conclusion": "SUCCESS",
      "name": "Platform macOS arm64",
      "run_id": 124105158030
    },
    {
      "conclusion": "SUCCESS",
      "name": "Platform macOS x64",
      "run_id": 124105158475
    },
    {
      "conclusion": "SUCCESS",
      "name": "Python 3.10",
      "run_id": 124105158044
    },
    {
      "conclusion": "SUCCESS",
      "name": "Python 3.11",
      "run_id": 124105158262
    },
    {
      "conclusion": "SUCCESS",
      "name": "Python 3.12",
      "run_id": 124105158184
    },
    {
      "conclusion": "SUCCESS",
      "name": "Python 3.14",
      "run_id": 124105158041
    },
    {
      "conclusion": "SUCCESS",
      "name": "Python lint",
      "run_id": 124105157927
    },
    {
      "conclusion": "SUCCESS",
      "name": "Website",
      "run_id": 124105157541
    }
  ],
  "check_observations": [
    {
      "checks": [
        {
          "conclusion": "SUCCESS",
          "name": "Gitar",
          "run_id": 124105161373,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/runs/124105161373"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform Linux arm64",
          "run_id": 124105158191,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105158191"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform Linux x64",
          "run_id": 124105158583,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105158583"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform Windows arm64",
          "run_id": 124105158069,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105158069"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform Windows x64",
          "run_id": 124105158231,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105158231"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform macOS arm64",
          "run_id": 124105158030,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105158030"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Platform macOS x64",
          "run_id": 124105158475,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105158475"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Python 3.10",
          "run_id": 124105158044,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105158044"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Python 3.11",
          "run_id": 124105158262,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105158262"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Python 3.12",
          "run_id": 124105158184,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105158184"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Python 3.14",
          "run_id": 124105158041,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105158041"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Python lint",
          "run_id": 124105157927,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105157927"
        },
        {
          "conclusion": "SUCCESS",
          "name": "Website",
          "run_id": 124105157541,
          "run_status": "completed",
          "status": "success",
          "url": "https://github.com/omry/arbiter/actions/runs/41068219431/job/124105157541"
        }
      ],
      "head_sha": "42decb66262591759a645ee8c1a9be799aaac03c",
      "id": "sha256:a813f9aa3c5399222c639ffa3dc4564d6616bf1f49e4a74639f02396a131cfe4",
      "required_checks": [
        "Gitar",
        "Platform Linux arm64",
        "Platform Linux x64",
        "Platform Windows arm64",
        "Platform Windows x64",
        "Platform macOS arm64",
        "Platform macOS x64",
        "Python 3.10",
        "Python 3.11",
        "Python 3.12",
        "Python 3.14",
        "Python lint",
        "Website"
      ],
      "status": "success"
    }
  ],
  "delivery_deferral_ledger_digest": "sha256:4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
  "delivery_deferrals": [],
  "findings": [],
  "pr": {
    "base_ref": "pr76",
    "base_sha": "d83ac6f56b24864eb41deae03789ec0f864a4d55",
    "body_digest": "sha256:cec39ea5f8a894056c527ba0df7cb45298da27de3cc7177d488084234d47aef8",
    "body_identity_version": 2,
    "diff_digest": "sha256:0f0fc28c9f50ebf053a860cbbedad87b7fe03d56f99845c5f70c60d153a583e9",
    "head_ref": "pr77",
    "head_sha": "42decb66262591759a645ee8c1a9be799aaac03c",
    "pr": 78,
    "repository": "omry/arbiter",
    "scope_authority": [
      {
        "digest": "sha256:b6511414b3a9b485542df83c8f7abfc499dc8d06e522819b48e162a562d21c57",
        "path": "docs/authentication/high-level-design.md"
      },
      {
        "digest": "sha256:38456f43776f8b47b1c5beb7cdbf5be5a34832267286a0135a489083980a4379",
        "path": "docs/authentication/implementation-plan.md"
      },
      {
        "digest": "sha256:7cbad8803d0ade4090289d22a681a01026782ade9785c731ac7a2d8a33b9c0e1",
        "path": "docs/authentication/portable-enrollment-lld.md"
      },
      {
        "digest": "sha256:d56e92a7cb01f131ba499650c4a5d7b2c8d17adf2cdc7d612eee7c5f53d07929",
        "path": "docs/authentication/requirements.md"
      }
    ],
    "title_digest": "sha256:2aefbe4b63be8a3ed6269828139ec27d64d67836eeb5d328c1d6c56ced06c08b"
  },
  "record_version": 4,
  "review_observations": [],
  "review_requests": [
    {
      "base_established_at": "2026-10-30T14:01:43Z",
      "base_ref": "pr76",
      "base_sha": "d83ac6f56b24864eb41deae03789ec0f864a4d55",
      "body_digest": "sha256:a3005e3624873e256560f2496279ae552e56f43c6fc318ebb82bff02a9195ae1",
      "created_at": "2026-10-30T14:13:34Z",
      "head_sha": "42decb66262591759a645ee8c1a9be799aaac03c",
      "id": 6524915052,
      "kind": "regular-review"
    }
  ],
  "review_results": [
    {
      "base_ref": "pr76",
      "base_sha": "d83ac6f56b24864eb41deae03789ec0f864a4d55",
      "body_digest": "sha256:8d0025ee1f1e2a3d2e39a33301cc19d2d07aa6c624f3301612e28df4a2ca4eee",
      "commit_id": "42decb66262591759a645ee8c1a9be799aaac03c",
      "id": 6524939849,
      "inline_message_ids": [],
      "request_comment_id": 6524915052,
      "result_kind": "clean",
      "status": "result",
      "submitted_at": "2026-10-30T14:14:46Z",
      "unresolved_thread_ids": [
        "PRRT_kwDOSmRaHM6x_tmx"
      ]
    }
  ],
  "revision_fingerprint": "sha256:813b237516a66c51ac26d5fca7bdb2ae592d67147235c4caea0a602e3d603f60",
  "rounds": [
    {
      "applied_fix_paths": [],
      "disposition_changes": [],
      "effective_diff_digest": "sha256:0f0fc28c9f50ebf053a860cbbedad87b7fe03d56f99845c5f70c60d153a583e9",
      "finding_ids": [],
      "invariants": [
        "Exact current complete native owning candidate and unchanged approved governing scope",
        "Enrolled-source custody/current portable validity and historical receipt recovery agree with approved2.10.2; public reuse remains closed",
        "All six actual full local checks and13 applicable nativeCI checks passed",
        "Actual current-context primary general, configured DBB and fresh history-aware independent general review are clean with verified strict PR-local proof"
      ],
      "outcome": "clean",
      "proposed_fix_paths": [],
      "resulting_head": "42decb66262591759a645ee8c1a9be799aaac03c",
      "review_observation_id": null,
      "review_request_id": 6524915052,
      "review_result_id": 6524939849,
      "reviewed_head": "42decb66262591759a645ee8c1a9be799aaac03c",
      "root_cause": "No current-slice defect or correction. Auxiliary literal URL alias observation was checked against current callers and original2.10.3 binding/2.10.4 public diagnostic ownership; no public reuse path is enabled here. Temporary detailed GitHubREST5xx evidence transport recovered read-only without CI reruns, source changes or approval suppression.",
      "round": 1,
      "unresolved_current_slice_findings": 0,
      "unresolved_design_blockers": 0
    }
  ],
  "schema": "awd:swe:pr-cycle-state",
  "version": 2
}

@omry
omry marked this pull request as ready for review October 30, 2026 14:10
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T14:14:47.735955Z 42decb6 Manual request
🔒 Security Review ⚠️ Failed 2026-10-30T14:10:05.018283Z
We couldn’t complete this review. Comment @codex security review to try again.
42decb6 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

The account paying for this security review has reached its Codex usage limits. The payer can check the Codex usage dashboard. For personal accounts, using credits requires enabling “Use credits for security reviews” in Code review settings. If you do not manage the paying account, contact this repository's admins.

@omry

omry commented Oct 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Exact head: 42decb6

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 42decb6626

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@omry omry added the approved PR passed review and required checks label Oct 30, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved PR passed review and required checks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant