Compose Forgejo private-input and authenticated decision build candidate
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a14bfc-9643-7872-aa12-98326dcf25e7
This commit is contained in:
parent
c29408ae67
commit
3fb031a47f
5 changed files with 4756 additions and 12 deletions
|
|
@ -1,7 +1,11 @@
|
|||
# Forgejo release preparation (build only)
|
||||
|
||||
The Apps Makefile targets package the independently reviewed seven-path Forgejo
|
||||
11.0.3 source extension. They never deploy, push, change default values or choose
|
||||
The Apps Makefile targets package the digest-bound 37-path Forgejo 11.0.3
|
||||
source candidate in `forgejo-security-extension.patch`. It combines the original
|
||||
three-group any-of gate, private secret-file input, private source-operation DB
|
||||
primitives and the producer-owned Access Engine client in the OIDC callback.
|
||||
Coordinator source tests and complete release checks are recorded separately;
|
||||
independent owner review and operational admission of this revision remain open. They never deploy, push, change default values or choose
|
||||
an operational image. Third-party application source is expanded only into a new
|
||||
`/tmp` workspace; this repository retains a release input lock and exact reviewed
|
||||
patch, not a second source-code tree. Upstream source ownership and publication
|
||||
|
|
@ -70,3 +74,40 @@ private secret-input boundary, type/case/descriptor re-freeze, current operation
|
|||
inverse sessions, durable journal and application/Helm writer exclusion are
|
||||
separate gates. Helm omission/rollback does not remove persisted OAuth source.
|
||||
The existing case gate is compatibility code, not a single-PDP exception.
|
||||
|
||||
## KeyCape identity and callback admission
|
||||
|
||||
The callback independently verifies the ID token against owner-admitted public
|
||||
keys, algorithms, issuer, audience and token type. Public trust is loaded from
|
||||
`FORGEJO_ACCESS_ENGINE_ADMISSION_FILE`; only an absolute private file reference
|
||||
is used for the PDP caller token. No admission file or operational keys are
|
||||
supplied by this build. New fields `tenant_source_claim` and
|
||||
`max_authentication_age` are mandatory. The KeyCape v0.3 profile uses
|
||||
`assurance_claim: assurance` and `tenant_source_claim: tenant_source`. Maximum
|
||||
identity age and maximum authentication age are separate positive durations
|
||||
chosen by the owner, not implicit defaults.
|
||||
|
||||
The signed assurance object preserves `level`, `methods`, boolean `mfa`,
|
||||
`source: key-cape` and integer `at`. Its authentication time must not follow
|
||||
issuance or the current time, and must satisfy the admitted authentication-age
|
||||
bound. Identity validity ends at the earliest token expiration, issued-at age
|
||||
bound or authentication-age bound. Directory, registration and default tenant
|
||||
provenance remain distinct in the request. Mutable UserInfo cannot replace
|
||||
these authenticated facts. Current UserInfo subject and the Goth subject must
|
||||
match the independently verified token; the three required group alternatives
|
||||
remain policy input.
|
||||
|
||||
The parser also represents valid lower-assurance facts. Application policy
|
||||
continues to decide authorization. The Check client and unchanged canonical
|
||||
signature bytes are a generated source slice of Access Engine ca0cb757; Forgejo
|
||||
adds no policy evaluator. Exact caller/policy/registry/signer/request/lifetime
|
||||
pins, an authenticated HTTPS connection and a current ALLOW are required.
|
||||
Synthetic callback fixtures test ALLOW, DENY and adverse cases, including an ID
|
||||
token serialized by the actual pinned KeyCape handler. Those fixtures do not
|
||||
prove an actual browser, factor, custody or native rollout.
|
||||
|
||||
The current integration covers this guarded OIDC callback. Ongoing application
|
||||
HTTP/API/Git/SSH paths, current operation/inverse sessions, durable private
|
||||
evidence and retention, PostgreSQL/native proof and exclusion of all release
|
||||
writers remain open in RAPPS-WP-0016-T08/T09 and NK-WP-0048-T43. An old image
|
||||
approval or source test result cannot admit this candidate.
|
||||
|
|
|
|||
4559
build/forgejo/forgejo-security-extension.patch
Normal file
4559
build/forgejo/forgejo-security-extension.patch
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -3,13 +3,13 @@
|
|||
"forgejo_version": "11.0.3",
|
||||
"source_archive_sha256": "1ddd8c926ca07d40436897971458ace7dcf1d3496a0813ab9e0d869edef2365c",
|
||||
"source_commit": "b81aa4d0807cc1e2d6a2fbafd0b75c46cc0ae237",
|
||||
"patch_sha256": "f2788b3f2bf84dbc0f94e232b6c9614a864b8123c09f9e44703d50d5e1b53257",
|
||||
"patch_sha256": "15cb7f13b1b1d1095cc344176ca337f705333a436a70ae803fcfd3d7f802ccf4",
|
||||
"go_archive_sha256": "3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8",
|
||||
"go_version": "1.24.3",
|
||||
"node_archive_sha256": "dafe2e8f82cb97de1bd10db9e2ec4c07bbf53389b0799b1e095a918951e78fd4",
|
||||
"node_version": "22.15.0",
|
||||
"source_date_epoch": 1752105237,
|
||||
"release_version": "11.0.3+nk48.f2788b3f",
|
||||
"release_version": "11.0.3+cust80.15cb7f13",
|
||||
"tags": "bindata timetzdata sqlite sqlite_unlock_notify",
|
||||
"runtime_base": "code.forgejo.org/forgejo/forgejo@sha256:41649dff5311664097d29b4d80620403f0b27e7c0eee0b8af79b132a37f3807b",
|
||||
"runtime_index_digest": "sha256:691657c7e64af7730a2e885e6d022cf16ae60724931c5392bd61838afadcaeba",
|
||||
|
|
@ -17,7 +17,59 @@
|
|||
"reviewed_outputs": [
|
||||
{
|
||||
"path": "cmd/admin_auth_oauth.go",
|
||||
"sha256": "1dd03f0bd23889a340a10fcc18d2e3a49270b79056aafd1b3baf01b18559b37f"
|
||||
"sha256": "d718d817c46f6393488a9c5a894b7535640cd0ec1a1ae3f72f8411a2bbec3b38"
|
||||
},
|
||||
{
|
||||
"path": "cmd/admin_auth_oauth_secret_linux.go",
|
||||
"sha256": "6741961f1df67c1afbf34c796e549425f0e04a0d0678c6eedb05f66d4754c64b"
|
||||
},
|
||||
{
|
||||
"path": "cmd/admin_auth_oauth_secret_linux_test.go",
|
||||
"sha256": "b28c2369dfab9bf2ca48e707e01b4394a36c8be5490cfe5bb658017bb626c4b2"
|
||||
},
|
||||
{
|
||||
"path": "cmd/admin_auth_oauth_secret_other.go",
|
||||
"sha256": "54056c989a4757e73db0252130e7c16bf16f5ec8eaaca2468f019ba2ef5c532d"
|
||||
},
|
||||
{
|
||||
"path": "go.mod",
|
||||
"sha256": "130138c4c3ecc29fa0d7f1e2eef0589ddf3b06071f3cc0448aa7b2326847653a"
|
||||
},
|
||||
{
|
||||
"path": "models/auth/source_operation.go",
|
||||
"sha256": "ef1b07ef6cf454015d00cde8588835f5118d829da91eb0303d37184859345a31"
|
||||
},
|
||||
{
|
||||
"path": "models/auth/source_operation_internal_test.go",
|
||||
"sha256": "af0f424d3a1fd2b29793b64baa1fa07284fee7ea0b7721c503db4efac0d871cb"
|
||||
},
|
||||
{
|
||||
"path": "models/auth/source_operation_process_test.go",
|
||||
"sha256": "40d33b11a01cb659f0bf6f8b545c4d79910e8c082a789060bcbc9cadeee965bd"
|
||||
},
|
||||
{
|
||||
"path": "models/auth/source_operation_test.go",
|
||||
"sha256": "77d311bca42f48faf3fbdc15c53582e3d8a6d9108a72ed7bb6172e5b88951428"
|
||||
},
|
||||
{
|
||||
"path": "models/db/context.go",
|
||||
"sha256": "d4c4acfcb8987071aecf5cd957b3821c8d2619a2696398d37c2970f2527686f7"
|
||||
},
|
||||
{
|
||||
"path": "models/db/engine.go",
|
||||
"sha256": "43683804d0c5bc6ead1dba0344c69dd196825cf3d5eb502af8d932a7b8207b96"
|
||||
},
|
||||
{
|
||||
"path": "models/db/sensitive_sql.go",
|
||||
"sha256": "06a298d0d6e628e6920384d4ddeef449e40c090841ebaa3f6d175725a45ae584"
|
||||
},
|
||||
{
|
||||
"path": "models/db/sensitive_sql_logging_test.go",
|
||||
"sha256": "d924b35d30686473caf29601cf51cc363ba68158cb4ef0981c9e2fc7b03c04b7"
|
||||
},
|
||||
{
|
||||
"path": "models/db/sensitive_sql_test.go",
|
||||
"sha256": "de6353c955047c3311747e4777b9f9b2195e9efb19160b971dd758dfc94cf31b"
|
||||
},
|
||||
{
|
||||
"path": "routers/web/admin/auths.go",
|
||||
|
|
@ -25,7 +77,31 @@
|
|||
},
|
||||
{
|
||||
"path": "routers/web/auth/oauth.go",
|
||||
"sha256": "081bcb94023d6e27289196bbe518bebba0a8a6082ea1a32d2794c5562075907b"
|
||||
"sha256": "58bff778e0dc17a521706289bf45c3e0d76a759a0874f76c379b3d1ddb419b17"
|
||||
},
|
||||
{
|
||||
"path": "services/auth/source/oauth2/access_engine.go",
|
||||
"sha256": "d5f07f9491ac2212410e1fa8c0248d68ba3a723e7ca99e363627c5292d187aa8"
|
||||
},
|
||||
{
|
||||
"path": "services/auth/source/oauth2/access_engine_assurance.go",
|
||||
"sha256": "42de751b1e9a243301d566260954813b770558ecb449639acaeab307fe788642"
|
||||
},
|
||||
{
|
||||
"path": "services/auth/source/oauth2/access_engine_assurance_test.go",
|
||||
"sha256": "44e7459f6c1106a264093c19d61d01a8365f6ad22682906552d832ba39d61dd3"
|
||||
},
|
||||
{
|
||||
"path": "services/auth/source/oauth2/access_engine_azp_test.go",
|
||||
"sha256": "5f94f43ade9a79b6b7ef529c80115a8c32acfece425dc8ed3f24e6ad839fc0ce"
|
||||
},
|
||||
{
|
||||
"path": "services/auth/source/oauth2/access_engine_callback_test.go",
|
||||
"sha256": "5cea36b630c895a9473dc876b7128526ddef65d9395b2fddc56343e162452472"
|
||||
},
|
||||
{
|
||||
"path": "services/auth/source/oauth2/access_engine_test.go",
|
||||
"sha256": "99edd6cfe3e834d73e0447a7915f52cc4ab7b82644669c5ae61963f850b447e8"
|
||||
},
|
||||
{
|
||||
"path": "services/auth/source/oauth2/providers_openid.go",
|
||||
|
|
@ -42,10 +118,54 @@
|
|||
{
|
||||
"path": "services/auth/source/oauth2/source.go",
|
||||
"sha256": "44e99883c2ec479427b3f72c73353fe33936eed2e5c962b2fa40803576aa5642"
|
||||
},
|
||||
{
|
||||
"path": "services/auth/source/oauth2/source_callout.go",
|
||||
"sha256": "6abba69df97afc62467f0328eaa5a6383cfb4900202a081dec4b84a21b37349c"
|
||||
},
|
||||
{
|
||||
"path": "third_party/access-engine-pep/LICENSE",
|
||||
"sha256": "ff413f361a3b3bf44cf50f110fbcc4837064d57eefbcef89df2b43997c6262b6"
|
||||
},
|
||||
{
|
||||
"path": "third_party/access-engine-pep/go.mod",
|
||||
"sha256": "fea700810e47c1ba5638b86a168f8531c083a6e1222ca80bd2a8947b2ea6f2c3"
|
||||
},
|
||||
{
|
||||
"path": "third_party/access-engine-pep/internal/sign/sign.go",
|
||||
"sha256": "0df9515922e90775ebbfac798361dcafb20da8a4213796b44e246b8a92046cde"
|
||||
},
|
||||
{
|
||||
"path": "third_party/access-engine-pep/pkg/api/canonical.go",
|
||||
"sha256": "a122a2e8cd524333b13c5939c7a3685e41efbe47497a64e0c7297c92b7f10d19"
|
||||
},
|
||||
{
|
||||
"path": "third_party/access-engine-pep/pkg/api/caring.go",
|
||||
"sha256": "1907156f0f889e7b9e9c14970cf7a86a20d00478a496efaf92c7231f27fec5e3"
|
||||
},
|
||||
{
|
||||
"path": "third_party/access-engine-pep/pkg/api/resource_manifest.go",
|
||||
"sha256": "f0fa4080287d389ed48c2b1d6af96cc62e57ef72c902333f677f964420be133f"
|
||||
},
|
||||
{
|
||||
"path": "third_party/access-engine-pep/pkg/decisionpep/client.go",
|
||||
"sha256": "0d57f6ddaca5c3f81ce426c0e8b14ba14ea5962096d3be5909aa456eef19eeba"
|
||||
},
|
||||
{
|
||||
"path": "third_party/access-engine-pep/pkg/decisionpep/client_test.go",
|
||||
"sha256": "1a6be3485f580f95a1f1406fb76e525f2c4bf02fe04a424cfe0095bb728e3f62"
|
||||
},
|
||||
{
|
||||
"path": "third_party/access-engine-pep/producer-source.json",
|
||||
"sha256": "c1d83e3d79f9860ffaa61ec19a6b3415e914d3058b11b07cdd05a7d1182cdceb"
|
||||
},
|
||||
{
|
||||
"path": "third_party/access-engine-pep/testsupport/signfixture/sign.go",
|
||||
"sha256": "fe4aa86f444dc20145aefbaca35b24f046264b2c5c8b4e3b057a4496b77a4d29"
|
||||
}
|
||||
],
|
||||
"lockfiles": {
|
||||
"go.mod": "652162a4a95c6d1c349d2a8c0b514def5abd837f001137b77b7b3f4a0f162d00",
|
||||
"go.mod": "130138c4c3ecc29fa0d7f1e2eef0589ddf3b06071f3cc0448aa7b2326847653a",
|
||||
"go.sum": "19c305c7e68de9d3f1bc0dda2de09c5d38597f1ee7fa411c7b36b92467ae1eaf",
|
||||
"package.json": "ab5c54ec7077501b50acf3ab5f1fff4f63a51abe99e720b8ecdc6cc6c78f39fc",
|
||||
"package-lock.json": "fdd5c2f891311be7c01b1907b418c243ca1f0f951fd4b4ee5b5e931c43493657"
|
||||
|
|
@ -59,5 +179,8 @@
|
|||
"/usr/lib/x86_64-linux-gnu/libc.a": "a40c7eae7581f977b65eddb81cbc799213a695749e039d966db55bdee4ac9621",
|
||||
"/usr/lib/x86_64-linux-gnu/libm.a": "420cd3c406f6f8c12deb3d1291146e9c091ee015a7c39eaf2237f01e80d6f0ae"
|
||||
},
|
||||
"runtime_base_config_sha256": "bc5a3df111729582faadebd01d126ba769e2b65d0c62f306f6bc79f4e562452b"
|
||||
"runtime_base_config_sha256": "bc5a3df111729582faadebd01d126ba769e2b65d0c62f306f6bc79f4e562452b",
|
||||
"patch_file": "forgejo-security-extension.patch",
|
||||
"candidate_review_status": "coordinator tested; independent owner review pending",
|
||||
"producer_source_commit": "ca0cb75729a63c9288b7333382d0fa3eb1e8c9a3"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ def prepare(a,work):
|
|||
check(getattr(a,n),LOCK[key])
|
||||
if not a.module_cache:raise ValueError('explicit public module cache required')
|
||||
cache=Path(a.module_cache).resolve();assert cache.is_dir()
|
||||
check(INPUTS/'required-claim-values.patch',LOCK['patch_sha256'])
|
||||
check(INPUTS/LOCK['patch_file'],LOCK['patch_sha256'])
|
||||
for n,h in LOCK['host_tools'].items():check(n,h)
|
||||
work.mkdir(parents=True);(work/'home').mkdir()
|
||||
with tarfile.open(a.source_archive) as t:
|
||||
|
|
@ -85,8 +85,8 @@ def prepare(a,work):
|
|||
for n in ['empty.npmrc','empty-global.npmrc']:(work/n).write_text('')
|
||||
if a.go_cache_seed:shutil.copytree(Path(a.go_cache_seed).resolve(),work/'gocache')
|
||||
if a.npm_cache_seed:shutil.copytree(Path(a.npm_cache_seed).resolve(),work/'npm-cache')
|
||||
subprocess.run(['/usr/bin/git','apply','--check',str(INPUTS/'required-claim-values.patch')],cwd=work/'source',check=True,env={'PATH':'/usr/bin:/bin','HOME':str(work/'home'),'GIT_CONFIG_NOSYSTEM':'1','GIT_CONFIG_GLOBAL':'/dev/null'})
|
||||
subprocess.run(['/usr/bin/git','apply',str(INPUTS/'required-claim-values.patch')],cwd=work/'source',check=True,env={'PATH':'/usr/bin:/bin','HOME':str(work/'home'),'GIT_CONFIG_NOSYSTEM':'1','GIT_CONFIG_GLOBAL':'/dev/null'})
|
||||
subprocess.run(['/usr/bin/git','apply','--check',str(INPUTS/LOCK['patch_file'])],cwd=work/'source',check=True,env={'PATH':'/usr/bin:/bin','HOME':str(work/'home'),'GIT_CONFIG_NOSYSTEM':'1','GIT_CONFIG_GLOBAL':'/dev/null'})
|
||||
subprocess.run(['/usr/bin/git','apply',str(INPUTS/LOCK['patch_file'])],cwd=work/'source',check=True,env={'PATH':'/usr/bin:/bin','HOME':str(work/'home'),'GIT_CONFIG_NOSYSTEM':'1','GIT_CONFIG_GLOBAL':'/dev/null'})
|
||||
save(work/'prepared.json',{'module_cache':str(cache),'lock_sha256':digest(INPUTS/'inputs.lock.json'),'public_archives_verified':True})
|
||||
checked_inputs(work)
|
||||
packages=json.loads((work/'source/package-lock.json').read_text())['packages']
|
||||
|
|
@ -136,6 +136,7 @@ def verify(work):
|
|||
run(work,'binary-version',bare+['--version'],outer)
|
||||
run(work,'new-cli-help',bare+['admin','auth','add-oauth','--help'],outer)
|
||||
assert '--required-claim-values' in (work/'new-cli-help.log').read_text()
|
||||
assert '--secret-file' in (work/'new-cli-help.log').read_text()
|
||||
run(work,'embedded-extract',bare+['embedded','extract','--include-vendored','--destination','/results','**'],outer)
|
||||
records={}
|
||||
for folder in ['public','options','templates']:
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ its historical text is retained and corrected here.
|
|||
|
||||
```task
|
||||
id: RAPPS-WP-0016-T09
|
||||
status: todo
|
||||
status: progress
|
||||
priority: high
|
||||
state_hub_task_id: "d3804638-c73d-5b9f-a456-4262f62f9e6b"
|
||||
```
|
||||
|
|
@ -261,3 +261,23 @@ issuer allowed/denied claim cannot manufacture authorization. Source integration
|
|||
needs real provider/callback/session wiring and meaningful producer-consumer
|
||||
positive/adverse tests before re-freezing the case and package. Existing break-
|
||||
glass/local account and linking behavior remain within the declared owner scope.
|
||||
|
||||
2026-10-18 source continuation for T07/T08/T09: the digest-bound build
|
||||
candidate now composes all 37 paths, including private secret-file input, actual
|
||||
source-state transactions/private SQL hooks, the producer-owned Access Engine
|
||||
Check client from ca0cb757 and guarded OIDC callback enforcement. The parser uses
|
||||
the actual KeyCape typed assurance/authentication-time/provenance contract; its
|
||||
actual issuer fixture/callback suite passes 71 test/subtest results, and selected
|
||||
composed packages pass 93 with no skips. The previous incompatible-string-claim
|
||||
rejection is retained. All patch postimages independently replay from the pinned
|
||||
official archive. Complete release build/verification is tracked in Custodian
|
||||
forgejo-keycape-claims-r1; earlier release outputs do not prove this revision.
|
||||
|
||||
This is coordinator source integration of a tested build candidate; independent
|
||||
owner review and formal operational admission remain open. T07's chart/private
|
||||
mount admission, T08's fresh authenticated operation/inverse and release-wide
|
||||
writer exclusion, T09's ongoing HTTP/API/Git/SSH paths, private evidence/retention,
|
||||
PostgreSQL/native proof and actual issuer/factor/custody acceptance remain open.
|
||||
No trust, deployed image, Helm values, source DB, user/link state or local sign-in
|
||||
is changed by this build-source update. The preserved legacy patch is historical;
|
||||
the input lock now explicitly selects forgejo-security-extension.patch.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue