What
repository_machine_grants is a live authorization input on the Git plane and has no path that creates a row outside tests. Every paired computer that authenticates to Git with its smct_ token is refused.
The chain
OpenAgentsWeb.Plugs.ForgeGitAuth.principal_for/1 accepts an smct_ token and assigns %{kind: :machine, id: machine.id} (lib/openagents_web/plugs/forge_git_auth.ex:57).
OpenAgents.Forge.GitHTTP routes that principal to machine_access/3 for both read (lib/openagents/forge/git_http.ex:250) and write (:276).
machine_access/3 calls OpenAgents.Repositories.machine_access?/3 (lib/openagents/forge/git_http.ex:343), which requires a repository_machine_grants row (lib/openagents/repositories.ex:805).
- The only writer is
OpenAgents.Repositories.grant_machine/4 (lib/openagents/repositories.ex:761). It has no caller in lib/. Its only callers are test/openagents/forge/git_http_test.exs:435 and :450.
There is no controller, LiveView, router route, or API surface that grants a computer repository access, and no revoke or delete path at all.
So a computer's Git request always resolves to 404 unknown repository, which is indistinguishable from an unauthorized one. The tests pass because they insert the grant directly.
Decide
Either wire the grant (a route, an audit action that already exists as repository.machine_grant.updated, and a revoke path), or remove the mechanism: the table, grant_machine/4, machine_access?/3, and the :machine principal branches in GitHTTP. Removing it narrows the Git plane's principal set, which is the honest shape if scoped forge credentials (IDENTITY-010, a separate mechanism through AssignmentCredentialVault) are the intended path instead.
If the table stays, OpenAgents.Vocabulary keeps its entries; if it goes, they go with it.
Found by
#134, while establishing which machine-named persistence surfaces are load-bearing.
What
repository_machine_grantsis a live authorization input on the Git plane and has no path that creates a row outside tests. Every paired computer that authenticates to Git with itssmct_token is refused.The chain
OpenAgentsWeb.Plugs.ForgeGitAuth.principal_for/1accepts ansmct_token and assigns%{kind: :machine, id: machine.id}(lib/openagents_web/plugs/forge_git_auth.ex:57).OpenAgents.Forge.GitHTTProutes that principal tomachine_access/3for both read (lib/openagents/forge/git_http.ex:250) and write (:276).machine_access/3callsOpenAgents.Repositories.machine_access?/3(lib/openagents/forge/git_http.ex:343), which requires arepository_machine_grantsrow (lib/openagents/repositories.ex:805).OpenAgents.Repositories.grant_machine/4(lib/openagents/repositories.ex:761). It has no caller inlib/. Its only callers aretest/openagents/forge/git_http_test.exs:435and:450.There is no controller, LiveView, router route, or API surface that grants a computer repository access, and no revoke or delete path at all.
So a computer's Git request always resolves to
404 unknown repository, which is indistinguishable from an unauthorized one. The tests pass because they insert the grant directly.Decide
Either wire the grant (a route, an audit action that already exists as
repository.machine_grant.updated, and a revoke path), or remove the mechanism: the table,grant_machine/4,machine_access?/3, and the:machineprincipal branches inGitHTTP. Removing it narrows the Git plane's principal set, which is the honest shape if scoped forge credentials (IDENTITY-010, a separate mechanism throughAssignmentCredentialVault) are the intended path instead.If the table stays,
OpenAgents.Vocabularykeeps its entries; if it goes, they go with it.Found by
#134, while establishing which machine-named persistence surfaces are load-bearing.