Skip to content

Prepare protected GitHub App material from admitted repository bindings - #141

Closed
freeqaz-openai wants to merge 21 commits into
codex/work-67b29cb859ed757e188a6ea7from
codex/work-6a1b2f7be4c40934bffb5af9
Closed

freeqaz-openai wants to merge 21 commits into
codex/work-67b29cb859ed757e188a6ea7from
codex/work-6a1b2f7be4c40934bffb5af9

Conversation

@freeqaz-openai

@freeqaz-openai freeqaz-openai commented Sep 12, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Prepare protected GitHub App material from admitted repository bindings. Namespace-owned APIs retain bounded Agent drafts, exact binding/Secret authorization, generation checks, PostgreSQL persistence and transactional audit.

Trusted preparation authenticates an immutable Kubernetes source and a separate pinned encryption key, then exposes bounded material to the issuer. AES-GCM envelopes, private custody state, currentness checks, descriptor cleanup and plaintext-buffer wiping remain enforced. Encrypted token storage preserves original commitments and refuses overwrite or conflicting recovery.

Controller composition now consumes the concrete issuer from apps/controller/src/providers/token/github. Protected crypto and token-store exports remain in OCC. Their implementations and the repository-access SQL are unchanged; that migration now follows main's Agent stop migration.

Dependency and behavior boundary

Based on #136. Bindings remain unverified; saving a draft does not invoke preparation. Nonempty repository selections fail deployment with REPOSITORY_VERIFICATION_UNAVAILABLE before revision, queue or Compute effects. Production Work admission, verified checkout and retained credential-owner composition remain separate integration work.

Current supplier refresh

This update receives #136 at 38ff25fcf8985b31c7f167e2704168fea7d7cc9d, including main's Agent stop and Go CLI changes. Agent storage projections and generated API responses retain both repository selections and desired runtime state. Repository-draft deployment refusal and stop/resume behavior remain documented together.

  • Repository transaction, binding-memory, platform-state-memory, and controller-lifecycle suites: 30 passed, 0 failed, 0 skipped, including Agent stop lifecycle coverage.
  • Fastify API integration suite: 16 passed, 0 failed, 0 skipped, covering stop-response schemas, authorization, and failure boundaries.
  • Project typecheck, generated OpenAPI/reference checks, workspace boundaries, documentation length, migration consistency, formatting of resolved files, and diff whitespace checks passed.
  • PostgreSQL migrations and database integration were not rerun locally for this head. Required hosted CI must assess this exact revision before merge.

Validation on the previously published head

At faed9fcd8facec195730b0acb0a950df01420bad, 61 selected provider-protocol, protected-crypto and real-filesystem token-store tests passed with zero failures or skips. Focused formatting, workspace boundaries and documentation length checks also passed. The documentation suite passed 16 of 17 tests; the generated-API fixture and additional OCC-root token-store test could not load the workspace dependencies.

The full typecheck and generated API checks now pass as recorded above; the earlier focused results remain evidence for the prior head. These checks do not qualify live GitHub, Kubernetes, PostgreSQL, installed custody or the regular Agent workflow.

@freeqaz-openai
freeqaz-openai force-pushed the codex/work-6a1b2f7be4c40934bffb5af9 branch from b37321e to 01690f8 Compare September 13, 2026 00:06
@freeqaz-openai
freeqaz-openai force-pushed the codex/work-0b9a3421ebdc5a1f155fa560 branch from f5f1ba3 to 38492c1 Compare September 13, 2026 00:06
@freeqaz-openai freeqaz-openai changed the title feat(repository): add unverified bindings and Agent drafts Add inactive repository binding definitions and Agent drafts Sep 13, 2026
@freeqaz-openai
freeqaz-openai marked this pull request as ready for review September 13, 2026 07:57
@freeqaz-openai
freeqaz-openai requested a review from a team as a code owner September 13, 2026 07:57
@freeqaz-openai
freeqaz-openai removed this pull request from stack #142 September 13, 2026 21:52
@freeqaz-openai
freeqaz-openai force-pushed the codex/work-6a1b2f7be4c40934bffb5af9 branch from 01690f8 to f65c8ea Compare September 14, 2026 08:57
@freeqaz-openai freeqaz-openai changed the title Add inactive repository binding definitions and Agent drafts Persist authenticated repository bindings and Agent selections Sep 14, 2026
@freeqaz-openai
freeqaz-openai changed the base branch from codex/work-0b9a3421ebdc5a1f155fa560 to codex/work-8ac03db200ba1d850e6a5f56 September 14, 2026 08:57
@freeqaz-openai
freeqaz-openai force-pushed the codex/work-8ac03db200ba1d850e6a5f56 branch from cb22ec7 to 977fd31 Compare September 14, 2026 11:27
@freeqaz-openai
freeqaz-openai force-pushed the codex/work-6a1b2f7be4c40934bffb5af9 branch from f65c8ea to e62e884 Compare September 14, 2026 11:49
@freeqaz-openai
freeqaz-openai force-pushed the codex/work-6a1b2f7be4c40934bffb5af9 branch from 12a29cb to 5c83721 Compare September 14, 2026 18:15
@freeqaz-openai
freeqaz-openai force-pushed the codex/work-8ac03db200ba1d850e6a5f56 branch from 977fd31 to 5f87ba8 Compare September 14, 2026 18:15
@freeqaz-openai
freeqaz-openai marked this pull request as draft September 14, 2026 20:25
@freeqaz-openai freeqaz-openai changed the title Persist authenticated repository bindings and Agent selections Prepare protected GitHub App material from admitted repository bindings Sep 14, 2026
@freeqaz-openai
freeqaz-openai changed the base branch from codex/work-8ac03db200ba1d850e6a5f56 to codex/work-67b29cb859ed757e188a6ea7 September 14, 2026 20:25
Comment thread tests/integration/postgres-repository-drafts.test.mjs
Comment thread tests/conformance/protected-github-app-material.test.mjs
Comment thread packages/occ/src/state/postgres-state.ts
Comment thread packages/occ/src/credential-custody-v1/protected-github-token-store.ts Outdated
Comment thread apps/controller/src/drivers/secret/kubernetes/protected-github-app-material.ts Outdated
Comment thread apps/controller/src/drivers/secret/kubernetes/protected-github-app-material.ts Outdated
Comment thread docs/reference/github-app-token-issuer.md
@freeqaz-openai
freeqaz-openai marked this pull request as ready for review September 15, 2026 18:12
Comment thread docs/reference/api.md
| `repositoryAccess.repositories[].bindingRef.id` | `string` | Yes | pattern: `^rb_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$` |
| `repositoryAccess.repositories[].bindingRef.kind` | `"repository_binding"` | Yes | — |
| `repositoryAccess.repositories[].bindingRef.namespaceId` | `string` | Yes | pattern: `^ns_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$` |
| `repositoryAccess.repositories[].checkoutRef` | `string` | Yes | min length: 1; max length: 256 |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

i'm concerned that we are nerfing the agent too much if we constraint it to a specific checkoutref or what refs it can checkout. its very typical for an agent to checkout from main. branch locally. push to a new ref. or review other prs

Comment thread docs/reference/api.md

| Name | In | Type | Required | Constraints |
| --- | --- | --- | --- | --- |
| `namespaceId` | path | `string` | Yes | pattern: `^ns_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$` |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

there is no need to put namespace in the payload since that part of the url parameters. we should also not let client set id.

POST /namespaces/{namespaceId}/repository-bindings

        "bindingRef": {
          "kind": "repository_binding",
          "namespaceId": "ns_11111111-1111-4111-8111-111111111111",
          "id": "rb_22222222-2222-4222-8222-222222222222"
        },

Comment thread docs/reference/api.md
| --- | --- | --- | --- |
| `appId` | `integer` | Yes | minimum: 1; maximum: 9007199254740991 |
| `installationId` | `integer` | Yes | minimum: 1; maximum: 9007199254740991 |
| `keySecretRef` | `object` | Yes | Exact OCC Secret reference. Shape: `{ "kind": "secret", "namespaceId": "ns_...", "id": "sec_..." }`. |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

id alone should be enough ehre. there is no reason to also add kind/namespace for secret ref

Comment thread docs/reference/api.md

| Field | Type | Required | Constraints |
| --- | --- | --- | --- |
| `appId` | `integer` | Yes | minimum: 1; maximum: 9007199254740991 |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

both appid, installationid and repositoryids as integers are github specific. anything we have as a top level api should be implementation agnostic

ideally, we'd implement repositories behind a pluggable interface (eg. GithubRepoDriver)

we can then configure repos in a way the driver understands

POST /namespaces/ns_example/reposets

{
  "name": "backend",
  "repositories": [
    "acme/api",
    "acme/worker"
  ],
  "driverConfiguration": {
    "appId": 123,
    "installationId": 456,
    "keySecretId": "sec_example"
  }
}

separately, driver is responsible for verifying access to repo and checkout. this means we have a way of authorizing different repositories (pxxxdriver, gitlabdriver, etc)

Comment thread docs/reference/api.md
| [`GET /namespaces/{namespaceId}/repository-bindings/{bindingId}`](#get-namespacesnamespaceidrepositorybindingsbindingid) | read an unverified Namespace-owned repository binding descriptor |
| [`PATCH /namespaces/{namespaceId}/repository-bindings/{bindingId}`](#patch-namespacesnamespaceidrepositorybindingsbindingid) | update an unverified Namespace-owned repository binding descriptor |

#### `POST /namespaces/{namespaceId}/repository-bindings`

@kevinlin-openai kevinlin-openai Sep 16, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

i don't like the name repository-bindings - anything with bindings reeks of llm slop. fine for internal impl but not public interface. can we call this reposet?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants