Skip to content

authority: ship the module's package, the hop's Version declares its policy, the hop declares authority 0.3.3 - #33

Merged
antoinetoussaint-byte merged 6 commits into
mainfrom
fix/authority-package-manifest
Oct 27, 2026
Merged

antoinetoussaint-byte merged 6 commits into
mainfrom
fix/authority-package-manifest

Conversation

@antoinetoussaint-byte

@antoinetoussaint-byte antoinetoussaint-byte commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Merge only together with, or after, codefly-dev/cli#1189. With CLI #1189 (420c4f63) the strict permission preflight passes on platform-core #114's head. With CLI main 89c76fde it refuses this head with conflicting policies for GET /version, because main does not let a gateway route inherit its proto method's policy. #1189 adds that, and it also leaves out the local authority's host-interface methods on a saas host.

What this fixes

On a saas host, every module behind the hop stopped before start:

cannot admit service before runtime start: module authority declares no package manifest,
so it names no release: …/modules/authority/module.package.codefly.yaml: no such file

#28 made authority/hop module-identity: true. The CLI's run admission admits every identity module except the host's own. On a saas host that includes the authority module, which shipped no package manifest.

The change

  • The package. modules/authority/module.package.codefly.yaml names the release codefly/authority 0.1.0 and the services the interface exports (local, hop, edge).

    • codefly generate contracts authority wrote each service's api-contracts, contracts/api/** and the catalog. --check is clean.
    • contracts.codefly.yaml and services/local/contract-surfaces.json are the inventory for the local authority's grpc listener, which spans packages. They follow the console's pattern.
  • The hop's Version declares a policy. It is any_checked_caller, as the console's Version is.

    • A host that implements codefly.dev/composition receives the policy of every method of a module it fronts, and refuses a method with none.
    • The option is vendored at hop/proto/authority/hop/v1/policy.proto the console's way, with VENDORED.md and a drift test (code/vendored_test.go).
    • buf.gen.yaml takes api.proto as its one input, so the option's bindings stay the hop library's.
    • codefly generate proto wrote the bindings and codefly generate contracts wrote the contracts. The no-proxy gate's provenance manifest records the reviewed digests: the only changes are the option's import and descriptor bytes, and the doc comment.
  • The hop's range. The hop declares codefly.dev/authority@>=0.3.3 <0.4.0, because RegisterAdmissionKey only exists from 0.3.3. Accounts at #114's saas pin implements 0.3.3.

  • tools/packagegate, the package gate. It refuses:

    • a module-identity module with no package
    • a manifest, catalog and contract files that disagree (core's own loaders and validators)
    • contracts that are stale against their service's proto tree or OpenAPI document
    • any published method a host fronting the module receives with no policy. It reads methods the way #1189's HostMethodPolicies does: each served procedure, its google.api.http routes, and each OpenAPI operation. A gateway route inherits the policy of the proto method that binds it. A service that stands in for a host is left out: one that runs as no module identity and exports an endpoint implementing a Codefly interface, which here is local.

    The refusal cases are a missing manifest, a moved/added proto, a moved OpenAPI document, an edited contract, the hop's Version unmarked, an unbound route unmarked, and a host-interface service that runs as the module.

Fix or hack: fix. Each piece is at its owner: the release in the module, the policy on the hop's method, the host-stand-in rule in the CLI (#1189).
Reused:

  • core's package and catalog loaders and validators
  • the CLI's generate contracts and generate proto
  • the console's vendored-policy pattern

The gate restates the CLI's policy read in about 200 lines because authority cannot import the CLI. It cites #1189 as its reference.

Proof

Strict preflight. Harness: gitops.CheckCompositionPermissions(strict=true), the call codefly deploy gitops makes. Workspace: platform-core #114 head 29e8d28, env local, host saas/accounts/connect, authority overridden in codefly.local.yaml to this branch.

CLI authority result
#1189 420c4f63 this PR ed10966 passed (also with the w-clipolicy-proof harness script)
main 89c76fde this PR ed10966 refused: conflicting policies for GET /version
main 89c76fde main 49101ae passed (no package, so the module is undeclared)

Saas-hosted run. CLI #1189, platform-core 29e8d28, scope apkg50, same roots as scripts/composition-check.sh. There was no cannot admit service and no names no release. With the hop's policy declared, the run also printed no permission-preflight warning:

(INFO) (launcher.deliver) delivered module=authority workloads=1 disposition=accepted generation=2
(INFO) (launcher.deliver) applied module=authority generation=2
>> evaluation/registry: Running on :62720
>> tracing/tracing: Running on :56463

The run then stopped for a local reason: tracing's gRPC port was already taken on this machine (bind: address already in use), from port-hash collisions with other runs here. An earlier run (apkg31, before the policy) had annotations Running too.

Not in this PR (audit D3 and D4), and why

  • The edge's installation range (>=0.2.0). Accounts at #114's pin implements installation 0.1.0. With the narrowed range the whole platform-core workspace fails to load (workspace_invalid … saas/accounts provides no version in range). It can narrow once accounts implements installation 0.2.0.
  • OfferService / ArtifactService in an interface. Declaring them is a contract move: it needs a version, shared cases and a home. It belongs in a separate proposal. They stay in local's inventory, because that is what the listener serves. On a saas host local is left out as a host stand-in.

Interaction with #32

#32 changes services/local/proto/host/authority/v1/authority.proto, so whichever lands second must re-run codefly generate contracts authority. packagegate turns that drift red.

🤖 Generated with Claude Code

antoinetoussaint-byte and others added 3 commits October 26, 2026 19:48
…he hop

A run admits every module-identity workload but the host's own. Since #28
made authority/hop module-identity, a run on a host other than the local
authority (a saas host) admits the authority module and needs its release,
and every module behind the hop failed before start: "module authority
declares no package manifest, so it names no release".

modules/authority/module.package.codefly.yaml names the release
(codefly/authority 0.1.0) and the services the interface exports (local,
hop, edge). Each service's api-contracts, contracts/api and the catalog are
written by `codefly generate contracts authority`; contracts.codefly.yaml
maps the local authority's grpc listener to the seven services it serves,
since that listener spans packages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…are fresh

tools/packagegate loads each module's package manifest and contract catalog
with core's own loaders and validators, requires a manifest wherever a
service declares module-identity (what a run admits), and compares each
contract with the sources codefly generate contracts writes it from: the
service's proto tree for a protobuf contract, its OpenAPI document for an
OpenAPI one. A proto change without regenerated contracts is red.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hop registers its admission key (RegisterAdmissionKey, authority 0.3.3)
but admitted any authority from 0.2.0, so a host below 0.3.3 rendered and
then had every module's verifier refuse every call. The range now starts at
0.3.3, so an older host is refused at render instead of at runtime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte antoinetoussaint-byte changed the title authority: ship the module's package manifest, so a host run admits the hop authority: ship the module's package manifest, so a host run admits the hop; the hop declares authority 0.3.3 Oct 27, 2026
antoinetoussaint-byte and others added 3 commits October 26, 2026 21:04
A host that implements codefly.dev/composition receives every method a
module it fronts publishes and refuses one with no policy. The hop's own
Version declared none, so the authority module was refused on a saas host
once its package existed. It now declares any_checked_caller, as the
console's Version does; the policy option is vendored next to the proto the
console's way, with its drift test, and api.proto is buf.gen.yaml's one input
so the vendored option's bindings stay the hop library's.

Bindings by `codefly generate proto`; contracts, catalog and manifest
digests by `codefly generate contracts authority`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/packagegate now reads the published contracts the way the CLI's
delivery reads them (codefly-dev/cli#1189's HostMethodPolicies): each
served procedure, its google.api.http routes and each OpenAPI operation,
a gateway route inheriting the policy of the proto method that binds it,
and a service that stands in for a host (no module identity, an endpoint
implementing a Codefly interface) left out. Any other method with no
policy is refused by name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…p bindings

codefly generate proto rewrote api.pb.go, api_grpc.pb.go and
genconnect/api.connect.go for the hop's policy option; the review found the
option's import and descriptor bytes and Version's doc comment, nothing else.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte antoinetoussaint-byte changed the title authority: ship the module's package manifest, so a host run admits the hop; the hop declares authority 0.3.3 authority: ship the module's package, the hop's Version declares its policy, the hop declares authority 0.3.3 Oct 27, 2026
@antoinetoussaint-byte
antoinetoussaint-byte merged commit f41cc2b into main Oct 27, 2026
16 checks passed
antoinetoussaint-byte added a commit that referenced this pull request Oct 27, 2026
… harden/review-followups

Conflicts were only generated artefacts: the authority-client library's
contract.binpb, catalog digest and library.codefly.yaml digest. Each side
recorded the contract of its own proto tree; neither digest is right for the
merged tree, so none was hand-picked: both are regenerated.

Regenerated with codefly v0.1.216 (built from tag d3af5843, which carries
cli#1189):
- generate proto in services/local: no change, the auto-merged bindings
  (#32's authority/v1, #34's installation/v1) are what the merged protos give.
- generate contracts authority: the local grpc contract carries #32's
  RegisterAdmissionKeyRequest.proof and #34's InstallationService.Current;
  the catalog, module.package.codefly.yaml and the vendored authority.proto
  copy follow. --check is clean.
- generate client --no-facade for authority-client: contract, catalog and
  library digest; its bindings are unchanged. Its contract is byte-identical
  to the module's local grpc contract, as on main.

Kept from #33: the hop's range codefly.dev/authority@>=0.3.3 <0.4.0 (a 0.3.3
authority ignores the additive proof, so the floor still holds) and the
package version 0.1.0 (#34 moved the contract under it unreleased too).
Kept from #32: the authority interface at 0.3.4 and the module implementing it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
crisfiorini-oss pushed a commit to crisfiorini-oss/cli that referenced this pull request Oct 27, 2026
…t stand in for it, and a gateway route carries its proto method's policy (codefly-dev#1189)

The strict permission preflight (render, run cluster, deploy module/service,
ci deploy) refused the authority module on a saas host once it ships a
package (codefly-dev/authority#33): its local service, which implements the
host interfaces and never runs on a saas host, put 32 unmarked methods into
the table the manifest carries; and marking the hop's Version made it worse,
"conflicting policies for GET /version", because the hop's http face publishes
the REST gateway's OpenAPI rendering of the same route, which cannot carry
the policy option.

- HostMethodPolicies is the table a module's manifest carries to env's host:
  the package's table less the services that stand in for that host (an
  exported endpoint implementing a Codefly interface the host.delivery service
  implements, and no module-identity). The preflight holds it, the native
  composition delivery sends it, and a caller's binding resolves against it.
  A module-identity service is always in it; require_method_policies still
  holds the whole package.
- Conflicts are refused per table (ServedMethodPolicies.Table), not across
  services that never meet in one.
- Within a service, an OpenAPI route that declares nothing and that one of
  the service's proto methods binds (google.api.http) carries that method's
  policy; a differing declaration is still refused.

Co-authored-by: Antoine Toussaint <312536060+antoinetoussaint-byte@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant