Codex Cannot Access a Private Repo

"unable to clone" — usually the Codex GitHub App isn't installed on the org, the repo isn't in its allowlist, or your OAuth token expired.

You select an org repo in Codex and get unable to clone or Repository not found. The repo is right there in your browser when you log into GitHub — but Codex can’t see it. This is almost always a GitHub App installation problem, not a Codex bug.

GitHub has three independent permission layers (user OAuth, App installation, App repository selection) and Codex needs all three. Most failures are one missing checkbox in one of those layers.

Common causes

Ordered by hit rate, highest first.

1. Codex GitHub App not installed on the org

You authorized Codex on your personal account, but the repo lives under acme-corp. The App needs a separate installation on every org you want it to see.

How to spot it: Visit https://github.com/organizations/acme-corp/settings/installations — if “Codex” isn’t listed, that’s the problem.

2. Repo not in the App’s “Repository access” allowlist

App is installed on the org, but configured with “Only select repositories” and the specific repo isn’t checked. Common after creating a new repo — the App doesn’t auto-include it.

How to spot it: Go to the Codex installation page, look at “Repository access.” If it says “Only select repositories (N)” and your repo isn’t in the list, check it.

3. Personal OAuth token expired

The user-level OAuth (separate from the App install) has a 7-30 day refresh cycle depending on your org’s SSO policy. After expiry Codex sees you as “unauthenticated” even though the App is installed.

How to spot it: Sign out of Codex and sign back in. If new orgs/repos suddenly appear, your token was stale.

4. SAML SSO not authorized for the App

Enterprise orgs enforce SAML — even installed apps must be SSO-authorized per user. The repo is invisible until you click “Authorize” via your org’s SSO portal.

How to spot it: Org settings → Authentication security → look for an unauthorized SAML grant for Codex. The org admin may need to whitelist it first.

5. Repo is on a paid plan tier the App doesn’t have access to

Free Codex tier doesn’t include private repos on some GitHub Enterprise Cloud orgs. You’ll see the org but no repos inside.

How to spot it: Public repos in the same org are visible, private repos aren’t. That’s a tier limit, not a permission bug.

6. Branch / submodule outside the granted scope

Codex can clone the repo but the task references a submodule pointing at a different private repo Codex doesn’t have access to. Error reads submodule update failed instead of clone failed.

How to spot it: Re-read the exact error message — submodule errors are distinct from clone errors.

Shortest path to fix

Ordered by ROI. Steps 1–3 fix the most common case (org install missing or scoped wrong).

Step 1: Verify the App is installed on the right org

Go to:

https://github.com/settings/installations

You’ll see every org/account that has Codex installed. If the target org isn’t listed:

  1. Click “Configure” on any existing install (or “New installation”).
  2. Choose the org owning your repo.
  3. Approve the install.

If you’re not an org owner, an admin has to approve. Send them the install link from https://github.com/apps/codex — they get a one-click “Install” button.

Step 2: Add the specific repo to “Repository access”

Once installed, click the Codex install for that org and scroll to “Repository access”:

○ All repositories
● Only select repositories
  [ ] acme-corp/marketing-site
  [x] acme-corp/api-server      ← needs this checkbox
  [ ] acme-corp/internal-tools

Tick the repo, click Save. Wait ~30 seconds for GitHub to propagate, then retry Codex.

For teams that frequently add new repos, switch to “All repositories” — saves the per-repo checkbox dance, at the cost of broader access.

Step 3: Re-run the OAuth flow

Even if the App is correct, your user token might be stale. In Codex:

  1. Settings → Connected accounts → GitHub → Disconnect.
  2. Reconnect; this triggers a fresh OAuth + SAML grant.
  3. Look for the SAML org consent screen if your enterprise uses SSO — easy to miss because it opens in a popup.

Step 4: Authorize SAML SSO (enterprise only)

If your org enforces SAML, the App install isn’t enough. Visit:

https://github.com/orgs/acme-corp/sso?return_to=%2Fsettings%2Finstallations

Click “Authorize” next to your name. This adds an SSO grant — Codex can now use your token to act on the org.

Step 5: For submodules, grant the submodule repo too

If the error is submodule update failed, the submodule lives in a different repo. Add that repo’s org/install to Codex separately:

# inspect submodules
git config --file .gitmodules --get-regexp url
# example output
# submodule.shared-types.url git@github.com:acme-corp/shared-types.git

Add acme-corp/shared-types to the same Codex App install (or a separate one if the submodule is in another org).

Step 6: For a quick unblock — use a Personal Access Token

If you can’t get App permissions sorted right now and just need the task to run, generate a fine-grained PAT scoped to the repo and paste it as a Codex secret:

Settings → Developer settings → Personal access tokens → Fine-grained tokens
Repository access: Only select repositories → [your repo]
Permissions: Contents (read/write), Pull requests (read/write), Metadata (read)

Add to Codex as GITHUB_TOKEN. The Codex setup script can then git clone https://x-access-token:$GITHUB_TOKEN@github.com/.... Use this as a stopgap — App install is the durable answer.

Prevention

  • When creating a new repo, immediately add Codex to its access list — bake this into your repo-creation checklist
  • For active teams, set Codex to “All repositories” on the org so new repos auto-include without manual ticking
  • Re-run the Codex OAuth flow every 30 days if your SSO has short token lifetimes; calendar reminder helps
  • Document the SAML SSO authorize step in the team onboarding doc — every enterprise dev hits it once
  • For monorepos with submodules, grant Codex to every submodule org up front
  • Avoid long-lived PATs as the primary auth — they leak more easily than App installs and don’t show in App audit logs

Tags: #Codex #Troubleshooting #GitHub #OAuth #Permissions