feat(server): make the context scope effective - #730
Open
decrypto21 wants to merge 10 commits into
Open
Conversation
…ty resolve the grant itself
…ing back to the served chain set
…ub feeds the grant path
…s the grant check
… test as documentation
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.
Closes #655. Stacked on #729, which the signing role needs to resolve a manifest at all.
A manifest granting
contextbehaved identically to one granting nothing. The runtime admitted thecaller and the authority holding the keys refused it again with the error the grant seam would have
produced, so the two outcomes were byte-identical. #454 introduced the scope, could not make it
effective, and removed it in
3f6ec081.Both seams change, not one.
3f6ec081revertedcreate_account_proofandring_vrf_signtocomparing the key handle against the calling product, so restoring the frontend consult is part of
this, not just teaching the authority. Reverting only the frontend leaves a granted call refused at
the authority; reverting only the authority leaves it refused at the frontend. Both are covered by
mutation pairs below.
The authority resolves the grant itself.
product_manifest::ring_vrf_key_access_grantedis theshared gate: the caller owns the key, or the owner's published manifest grants it
contextand theuser has not already refused. Both authorities call it, from both methods. It is not handed a
verdict from the capability layer, because on a paired host the request arrives over the wire and a
relayed boolean would take the manifest out of the decision entirely: the peer would reach every
handle on the device by setting one field, rather than only the handles a publisher really granted.
calling_product_idon that path is a SCALE field decoded from the peer's message, which is why thecomponent holding the keys has to decide for itself.
The handle is normalized in the gate, not only at the frontend.
sso_responderhands a wirerequest to the authority untouched, so without this an owner naming its own key
PEOPL.DOTover thewire was refused where the same request from a local product runtime succeeded.
3f6ec081's messageclaims casing cannot do that, which was true of the frontend and false of the wire path. A handle
that does not normalize takes the uniform refusal.
A prior denial still wins. The stored
AccountAccessdecision is read before the manifest, andread only, so a grant lookup never raises the prompt that would settle an undecided one.
The session is consulted before the grant on
create_account_proof, matchingring_vrf_sign.The other order makes the pair of refusals a probe for who granted whom: with no session a granting
target answers
Rejectedand a non-granting oneNotAllowlisted. That had to land with the grantrather than after it.
End to end
make e2e-cross-product-ringvrfis the sibling ofe2e-cross-product-storageand the first runanywhere in which a cross-product ring-VRF call is granted rather than refused. Every other run of
this path asserts the refusal, including the generated
account-create-account-proofexample andring-vrf-e2e.ts, which is how the scope shipped inert.Real CLI, real wire frames, real chain, grant resolved from
--product-configthrough the manifestcache and the same adjudication code production runs. The byte comparison against the owner's own
signature is the assertion that matters: a host deriving the key from the caller still returns a
valid 64-byte signature.
Verification
1263 tests,
cargo clippy --workspace --all-targets --all-features -- -D warningsclean,cargo +nightly fmt --checkclean. Battery unchanged against baseline.Mutation pairs, each against a production function and each checked for which assertion goes red:
Ok(())without consulting the manifesta_request_cannot_substitute_for_the_owners_manifest, first assertiongrants_scopenever grantsa_stored_denial_survives_a_context_grant_at_the_authorityallstops satisfying a narrower scopea_grant_of_all_satisfies_context_at_the_authoritya_context_grant_lets_a_foreign_product_prove_with_the_owners_keywith_no_session_a_proof_refusal_never_discloses_whether_a_grant_existsa_context_grant_lets_a_foreign_product_sign_with_the_owners_keythe_signing_role_adjudicates_grants_against_the_asset_hub_it_installedcontextfrom the e2e fixturemake e2e-cross-product-ringvrf, granted phaseNot covered
No end-to-end run drives the pairing wire path. The authority behaviour there is unit tested by
driving
create_proofandring_vrf_signdirectly, the waysso_responderdoes, but a real pairedpeer needs two hosts.
derive_ring_vrf_entropystill reads the raw handle (signing_host.rs), so over the wire a handlespelled differently would derive a different key. Masked today because the registry lookup fails
first, and out of scope here: the fix belongs at the wire entry point, which five other calls pass
through.
an_owner_naming_its_own_key_in_another_spelling_is_admitted_over_the_wireassertsKeyNotRegisteredexactly, so it goes red when that is closed.