Repository navigation
feat(controllers): read a private catalog with an App installation token - #250
Merged
Merged
Conversation
gitsource.LoadAuth fetches with a token as HeadAuth does; controllers.GitSource mints one per Head/Load through its Token func; factory serve gets --catalog-app-id and --catalog-app-key-ref and builds a one-identity minter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w pass 1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gusfcarvalho
left a comment
Contributor
There was a problem hiding this comment.
ccf-review: COMMENT
1 Should-fix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Task: IMPROVEMENTS item 8, stack A PR A1 of 3: fx/cat-a1-private-catalog on main.
Summary
factory servecan now read a private catalog repository (CCF's prod catalog moves tocompliance-framework/factory-catalog) with an installation token of a GitHub App of its own, since the App keys the catalog's Provider declares can't bootstrap reading that catalog.gitsource.LoadAuth(internal/catalog/gitsource):Loadwith anAuth. The fetch sends the token exactly asHeadAuthdoes (anAuthorizationheader scoped to the repo URL, in git's process-scoped config; never the URL or argv), and every error is redacted withAuth.secrets.Loadcalls it with a zeroAuth, so its behaviour is unchanged. The URL checkHeadAuthhad inline is nowAuth.check, shared by both.controllers.GitSource.Token: when set,HeadandLoadmint a token forowner/namefirst (RepoOnHost) and passgitsource.Auth{Token: tok}. A mint error (or an empty token) fails the call wrapped, with no anonymous fallback; a Repo that isn'thttps://<host>/<owner>/<name>[.git]is an error at first use.Headon a pinned commit SHA mints nothing.String()stays credential-free.--catalog-app-id Nand--catalog-app-key-ref name/key(the PEM fromFACTORY_SECRET_<NAME>_<KEY>, as for catalog secretRefs). Validation: the two go together; neither combines with--catalog-diror--dev-fake-providers; the ref must bename/key; the variable must be set; and--catalog-repomust behttps://<git host>/<owner>/<name>on the git host of--github-api-url(defaultgithub.com), so the token can't be sent to another host. Errors name flags and variables, never values.catalogSourceinserve_app.go): onetokens.Minterwith the single identitycatalog,APIURL=--github-api-urlelsehttps://api.github.com, serve's clock, logger and HTTP client;GitSource.Tokenmintsprovider.ReadOnlyRequest("catalog", repo, 10m).catalogSourceis now built once and returns an error, so a bad PEM fails at startup throughtokens.New.deploy/poc/README.md§4,FACTORY_CATALOG_APP_ID(optional) inrun.shand.env.example(adds both flags withccf-factory-app/private-key), and the flag row plus validation clause in the serve LLD (api-server.md).Verification
make reviewable: passes (generated-code check, golangci-lint v2.11.4 with the shared config,go test -race -count=1 ./..., catalog checks66 cases, 66 ok, vacuum 100/100).TestLoadAuth(gitsource, over the local smart-HTTPS git serverauth_test.goalready has): a private repo loads with the token and fails anonymously or with a wrong token; a ref named like the token makes git print it in its error, and the test checks it is redacted (it is:couldn't find remote ref redacted); a token on afile://URL is refused.TestGitSourceToken/TestGitSourcePinnedHead(controllers, with injectedheadAuth/loadAuth): the minted token reaches bothHeadandLoad; with noTokenboth are anonymous; a mint error, an empty token, and ssh, http, non-repo and user-info URLs fail without any gitsource call; a pinned commit needs no mint.TestParseServeConfig: 12 new rows for the flag validation above (including GHE and the key value never appearing in an error).TestCatalogSourceToken(cmd/factory, againstgithubtest): the wiredGitSource.Tokenmints a real (fake-server) installation token for the catalog repo as App 7; a bad PEM failscatalogSourcewithout echoing it.contents: readtoken readscompliance-framework/factory-catalogend to end:catalog loadedwith the repo's commit assha; without the App installed on the repo, startup fails withmint a read token for the catalog repository compliance-framework/factory-catalog: ….Design decisions
Tokenis set (unlikeGitSkills.Token): a private catalog read anonymously only adds a second, confusing error; catalog-sync already retries and keeps the last good catalog.GitSourcechecks the URL's form, and serve checks the host is the App's git host, because the token is minted for that host.For triage
internal/controllers,cmd/factory serve), plus theAuthparameter in dispatcher-core'sinternal/catalog/gitsourceas the spec allows. It also editsdeploy/poc/{README.md,run.sh,.env.example}(poc-rollout's kit; named by the spec) anddesign/workstreams/dispatcher-runtime/LLD/api-server.md(not named by the spec; added by self-review so the LLD's flag table matches serve).deploy/poc/run.shhard-codes--catalog-repo https://github.com/ContainerSolutions/factory(thecatalog=(…)block), soFACTORY_CATALOG_APP_IDalone reads this public repo with a token. To readcompliance-framework/factory-catalogtoday, pass--catalog-repo https://github.com/compliance-framework/factory-catalogas an extra argument torun.sh(extra arguments come last, so they win). Proposed fix: A3, which rewrites §4 and stops the default, addsFACTORY_CATALOG_REPOtorun.shand.env.example.🤖 Generated with Claude Code