# [OLD] Trust Policy Scoping Scenarios Scoping down the trust-policy to a particular registry or repository or namespace allows customer to have fine-grain control over signature verification. This document lists various scenarios where scoping of trust policy will be helpful and examples of trust policy using a scope that supports longest-prefix matching on repository URI. Related PR: [notaryproject/notaryproject/pull/119](https://github.com/notaryproject/notaryproject/pull/119/files?short_path=bab1489#diff-bab14897801fe47838fadd7f0ebd867e81ce66e098785175f4c1ec368bbe406a) which adds longest prefix match based scoping on `${registry-name}/${namespace}/${repository-name}`. ## Scenarios ### Various registries - Amazon ECR: `${AccountId}.dkr.ecr.${Region}.amazonaws.com/teamA/boo` - Amazon ECR Public: `public.ecr.aws/teamA/boo` - ACR: `${RegistryName}.azurecr.io/teamA/boo` - ACR Public: `mcr.microsoft.com/teamA/boo` - Docker Hub Container Registry: `docker.io/teamA/boo` - Red Hat Quay: `quay.io/teamA/boo` - JFrog Container Registry: `${ServerName}.jfrog.io/teamA/boo` public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest public.ecr.aws/cloudwatch-agent/cloudwatch-agent:sha256:sadadadadadsvfdsfvds ### Public and Private Repositories Enterprises might consume some images from public repositories and some from their private repositories. #### Example The URIs for repositories are: - `public-registry.io/Image1` - `another-public-registry.com/Image2` - `wabbit-networks.io/javaImage` - `wabbit-networks.io/pythonImage` ##### Trust Store ```json { "version": "1.0", "trustStores": { "private-repo-ts": {...}, "public-repo-ts": {...} } } ``` ##### Trust Policy ```json { "version": "1.0", "trustPolicies": [ { "name": "private-repo-tp", "scope": ["wabbit-networks.io/"], "trustStores": [ "shared-1-ts" ], "expiryValidations": {...}, "revocationValidations": {...} }, { "name": "public-repo-tp", "scope": [ "public-registry.io/Image1", "another-public-registry.com/Image2" ], "trustStores": [ "public-repo-ts" ], "expiryValidations": {...}, "revocationValidations": {...} }, ] } ``` ### Multi Region Registeries In some cases, registries like Amazon ECR have the region name and account number included in the repository URI. An enterprise might want to replicate and consume images from multiple regions/accounts for higher resiliency or compliance. #### Example The URIs for repositories are: - `12345678910.dkr.ecr.us-east-2.amazonaws.com/teamA/boo` - `12345678910.dkr.ecr.us-west-2.amazonaws.com/teamA/boo` - `10987654321.dkr.ecr.us-west-2.amazonaws.com/teamA/boo` ##### Trust Store ```json { "version": "1.0", "trustStores": { "teamAImages-ts": {...} } } ``` ##### Trust Policy ```json { "version": "1.0", "trustPolicies": [ { "name": "aws-tp", "scope": [ "12345678910.dkr.ecr.us-east-2.amazonaws.com/teamA/boo", "12345678910.dkr.ecr.us-west-2.amazonaws.com/teamA/boo", "10987654321.dkr.ecr.us-west-2.amazonaws.com/teamA/boo" ], "trustStores": [ "teamAImages-ts" ], "expiryValidations": {...}, "revocationValidations": {...} } ] } ``` ### Prod and Pre-prod Registries Enterprises might have different registries for prod and pre-prod environments. Also, they might want to enforce the different controls for pre-prod and prod environments. #### Example The URIs for repositories are: - `wabbit-networks.io/software` - `preprod-wabbit-networks.io/software` ##### Trust Store ```json { "version": "1.0", "trustStores": { "prod-ts": {...}, "pre-prod-ts": {...} } } ``` ##### Trust Policy ```json { "version": "1.0", "trustPolicies": [ { "name": "prod-trust-policy", "Scope": [ "wabbit-networks.io/software" ], "trustStores": [ "prod-ts"], "expiryValidations": {...}, "revocationValidations": {...} }, { "name": "preprod-trust-policy", "scope": [ "preprod-wabbit-networks.io/software" ], "trustStores": [ "prod-ts", "preprod-ts" ], "expiryValidations": {...}, "revocationValidations": {...} } ] } ``` ### Organization and Team specific Singing Key Enterprises might have some images that are shared across all teams and then some teams have their product specific images. #### Example The URIs for repositories are: - `wabbit-networks.io/softwares/platform/some-sidecar` - `wabbit-networks.io/softwares/TeamA/java` ##### Trust Store ```json { "version": "1.0", "trustStores": { "org-ts": {...}, "team-ts": {...} } } ``` ##### Trust Policy ```json { "version": "1.0", "trustPolicies": [ { "name": "team-trust-policy", "scope": ["wabbit-networks.io/softwares/"], "trustStores": [ "org-ts", "team-ts" ], "expiryValidations": {...}, "revocationValidations": {...} } ] } ``` ### One Team Multiple Repositories Teams might have multiple registries(one per product) and they might sign some of them with a common certificate and some with individual certificates. #### Example The URIs for registries are: - `wabbit-networks.io/teamA/java/product1` - `wabbit-networks.io/teamA/java/product2` - `wabbit-networks.io/teamA/java/productA` ##### Trust Store ```json { "version": "1.0", "trustStores": { "common-ts": {...}, "producta-ts": {...} } } ``` ##### Trust Policy ```json { "version": "1.0", "trustPolicies": [ { "name": "common-tp", "scope": [ "wabbit-networks.io/teamA/java" ], "trustStores": [ "common-ts" ], "expiryValidations": {...}, "revocationValidations": {...} }, { "name": "producta-tp", "scope": [ "wabbit-networks.io/teamA/java/productA" ], "trustStores": [ "producta-ts" ], "expiryValidations": {...}, "revocationValidations": {...} } ] } ``` ### Catch-All Trust Policy The scenario where a team wants to use stringent controls for certain repositories and default controls for the rest of repositories. #### Example The URI for the repository is: - `wabbit-networks.io/teamA/boo` ##### Trust Store ```json { "version": "1.0", "trustStores": { "private-repo-ts": {...}, "long-list-ts": {...} } } ``` ##### Trust Policy ```json { "version": "1.0", "trustPolicies": [ { "name": "private-repo-tp", "scope": [ "wabbit-networks.io/teamA/" ], "trustStores": [ "private-repo-ts" ], "expiryValidations": {...}, "revocationValidations": {...} }, { "name": "catchall-tp", "trustStores": [ "long-list-ts" ], "expiryValidations": {...}, "revocationValidations": {...} } ] } ``` ### Recommendation **Use longest-prefix matching(at least for v1) as it's unambiguous and deterministic.** Also, the user can script the generation of trust policy to support complex use-cases. ## Appendix ### Wildcard vs longest-prefix matching | Criteria | Longest-prefix | Wildcard | | -------- | -------- | -------- | | **Deterministic** | Yes | No (unless we add priority field) | | **Multi-region registries support** | Cumbersome | Convenient | Wildcards(`*`) provides a better experience for multi-region registries use-cases but it comes with its own set of challenges: - In case of overlapping scope we will need to define the priority of trust policies i.e. in what order policies should be evaluated. For example: ```json // URI of repository: // 12345678910.dkr.ecr.us-east-2.amazonaws.com/teamA/boo { "version": "1.0", "trustPolicies": [ { "name": "one-account-all-regions", "scope": [ "12345678910.dkr.ecr.*.amazonaws.com/teamA/boo" ], "trustStores": [ "ts-1" ], "expiryValidations": {...}, "revocationValidations": {...} }, { "name": "all-accounts-all-us-regions", "scope": [ "*.dkr.ecr.us-*.amazonaws.com/teamA/boo" ], "trustStores": [ "teamAImages-ts" ], "expiryValidations": {...}, "revocationValidations": {...} }, { "name": "all-accounts-all-regions", "scope": [ "*.dkr.ecr.*.amazonaws.com/teamA/boo" ], "trustStores": [ "ts-2" ], "expiryValidations": {...}, "revocationValidations": {...} } ] } ``` This problem can be solved by defining ordering/prioritization rules such as: - **Implicit ordering:** Policies are evaluated in the order they exist in JSON. JSON array preserves the order of objects [rfc7159](https://www.rfc-editor.org/rfc/rfc7159.html#page-3). - **Explicit ordering:** - Introduce a new field called `priority` which dictates the order in which policies should be picked for evaluation. ```json "scope": [ { "registry-uri": "*.dkr.ecr.us-*.amazonaws.com/teamA/boo", "priority": 1 } ] ``` - Document containing evaluation rules like - Scope with no wildcard takes priority over other scopes - Scope will less number of wildcard takes priority over scope with more number of wildcards - If two scopes have the same number of wildcards we will come up with some rules (TBD) ###### tags: `notary`