Skip to content

Isolate lockdown repository access cache per request identity #3107

Description

@SamMorrowDrums

Describe the bug

In HTTP mode the lockdown repository access cache is shared across callers. Entries are keyed on owner/repo alone inside a process-wide cache2go table, so a trust decision computed under one caller's credentials — repository visibility, author push access — can be served to a different caller whose own credentials were never checked.

Stdio mode is not affected: it runs a single cache for one process-wide identity.

Affected version

Current main as of 2026-08-19.

Steps to reproduce the behavior

  1. Run the server in HTTP mode.
  2. Issue a lockdown-gated request for owner/repo as identity A.
  3. Issue the same request for the same owner/repo as identity B.
  4. Observe that B is served A's cached trust decision, without B's own credentials being used.

Expected vs actual behavior

Expected: a cached trust decision is scoped to the identity whose credentials produced it.

Actual: decisions are shared process-wide under a bare owner/repo key.

Note on cache freshness

The cache's sliding/idle expiry is not a defect. cache2go refreshes an entry's TTL on access by design, and this cache has always relied on that — the hand-rolled cache it replaced kept the same semantics. A hot repository stays cached; idle entries are reclaimed.

Whether repo-access decisions should additionally carry a fixed maximum age is a separate freshness question rather than an isolation one, and is deliberately not part of this fix. A fixed age makes every hot repository refetch on a timer, so it would want singleflight (or a shared store such as Redis) and possibly stale-while-revalidate to avoid a refetch stampede. Worth revisiting on its own terms.

Logs

N/A

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions