diff --git a/docs/metatype.dev/docs/reference/policies/index.mdx b/docs/metatype.dev/docs/reference/policies/index.mdx index 50d8f20d4..e5f49035c 100644 --- a/docs/metatype.dev/docs/reference/policies/index.mdx +++ b/docs/metatype.dev/docs/reference/policies/index.mdx @@ -37,24 +37,8 @@ Policies are hierarchical in the sense that the request starts with a denial, an - `DENY`: Denies access to the parent and all its descendants, disregarding inner policies. - `PASS`: Allows access to the parent, each descendant will still be evaluated individually (equivalent to having no policies set). -### Inline chain +### Chaining policies -If you have `foo.with_policy(A, B).with_policy(C)` for example, it will be merged into a single chain `[A, B, C]`. +If you have `foo.with_policy(A, B).with_policy(C)` for example, it will evaluated in batch as `[A, B, C]`. -The evaluation is as follows: - -- `ALLOW` and `DENY` compose the same as `true` and `false` under the logical `AND` operator. -- `PASS` does not participate. - -Or more concretely: - -- `ALLOW` & Other -> Other -- `DENY` & Other -> `DENY` -- `PASS` & Other -> Other (`PASS` is a no-op) - -Examples: - -- `[DENY, DENY, PASS, ALLOW]` -> `DENY` -- `[ALLOW, PASS]` -> `ALLOW` -- `[PASS, PASS, PASS]` -> `PASS` -- `[]` -> `PASS` (no policies) +If one or more policies fail (`DENY`), the type will be inaccessible. diff --git a/examples/typegraphs/execute.py b/examples/typegraphs/execute.py index 7467a45cb..84284fa0a 100644 --- a/examples/typegraphs/execute.py +++ b/examples/typegraphs/execute.py @@ -53,7 +53,7 @@ def roadmap(g: Graph): admins = deno.policy( "admins", """ - (_args, { context }) => !!context.username ? 'ALLOW' : 'DENY' + (_args, { context }) => !!context.username ? 'PASS' : 'DENY' """, ) diff --git a/examples/typegraphs/execute.ts b/examples/typegraphs/execute.ts index 55c111c1f..1e61d0505 100644 --- a/examples/typegraphs/execute.ts +++ b/examples/typegraphs/execute.ts @@ -52,7 +52,7 @@ await typegraph( const admins = deno.policy( "admins", ` - (_args, { context }) => !!context.username ? 'ALLOW' : 'DENY' + (_args, { context }) => !!context.username ? 'PASS' : 'DENY' `, ); diff --git a/examples/typegraphs/func.py b/examples/typegraphs/func.py index aa6d5bb17..cfc4cda60 100644 --- a/examples/typegraphs/func.py +++ b/examples/typegraphs/func.py @@ -58,7 +58,7 @@ def roadmap(g: Graph): admins = deno.policy( "admins", - "(_args, { context }) => !!context.username ? 'ALLOW' : 'DENY'", + "(_args, { context }) => !!context.username ? 'PASS' : 'DENY'", ) # skip:end diff --git a/examples/typegraphs/func.ts b/examples/typegraphs/func.ts index e2f1f17ca..90ccdfb28 100644 --- a/examples/typegraphs/func.ts +++ b/examples/typegraphs/func.ts @@ -56,7 +56,7 @@ await typegraph( const admins = deno.policy( "admins", - "(_args, { context }) => !!context.username ? 'ALLOW' : 'DENY'", + "(_args, { context }) => !!context.username ? 'PASS' : 'DENY'", ); // skip:end diff --git a/examples/typegraphs/policies.py b/examples/typegraphs/policies.py index d701796bd..a2557ba66 100644 --- a/examples/typegraphs/policies.py +++ b/examples/typegraphs/policies.py @@ -25,7 +25,7 @@ def policies(g: Graph): ) user_only = deno.policy( "user_only", - "(args, { context }) => context?.username === 'user' ? 'ALLOW' : 'DENY'", + "(args, { context }) => context?.username === 'user' ? 'PASS' : 'DENY'", ) g.auth(Auth.basic(["admin", "user"])) diff --git a/examples/typegraphs/policies.ts b/examples/typegraphs/policies.ts index 0f0d44339..17c9394b2 100644 --- a/examples/typegraphs/policies.ts +++ b/examples/typegraphs/policies.ts @@ -23,7 +23,7 @@ typegraph( ); const user_only = deno.policy( "user_only", - "(args, { context }) => context?.username === 'user' ? 'ALLOW' : 'DENY'", + "(args, { context }) => context?.username === 'user' ? 'PASS' : 'DENY'", ); g.auth(Auth.basic(["admin", "user"])); diff --git a/examples/typegraphs/programmable-api-gateway.py b/examples/typegraphs/programmable-api-gateway.py index 8e9446ced..f78826058 100644 --- a/examples/typegraphs/programmable-api-gateway.py +++ b/examples/typegraphs/programmable-api-gateway.py @@ -18,7 +18,7 @@ def programmable_api_gateway(g: Graph): public = Policy.public() roulette_access = deno.policy( - "roulette", "() => Math.random() < 0.5 ? 'ALLOW' : 'DENY'" + "roulette", "() => Math.random() < 0.5 ? 'PASS' : 'DENY'" ) my_api_format = """ diff --git a/examples/typegraphs/programmable-api-gateway.ts b/examples/typegraphs/programmable-api-gateway.ts index b07471438..ebaf52df3 100644 --- a/examples/typegraphs/programmable-api-gateway.ts +++ b/examples/typegraphs/programmable-api-gateway.ts @@ -17,7 +17,7 @@ typegraph( const pub = Policy.public(); const roulette_access = deno.policy( "roulette", - "() => Math.random() < 0.5 ? 'ALLOW' : 'DENY'", + "() => Math.random() < 0.5 ? 'PASS' : 'DENY'", ); // skip:next-line diff --git a/examples/typegraphs/reduce.py b/examples/typegraphs/reduce.py index 7a5029fef..62afe9c6f 100644 --- a/examples/typegraphs/reduce.py +++ b/examples/typegraphs/reduce.py @@ -51,7 +51,7 @@ def roadmap(g: Graph): admins = deno.policy( "admins", - "(_args, { context }) => !!context.username ? 'ALLOW' : 'DENY'", + "(_args, { context }) => !!context.username ? 'PASS' : 'DENY'", ) g.expose( diff --git a/examples/typegraphs/reduce.ts b/examples/typegraphs/reduce.ts index fda53d83d..0460066d8 100644 --- a/examples/typegraphs/reduce.ts +++ b/examples/typegraphs/reduce.ts @@ -49,7 +49,7 @@ typegraph( const admins = deno.policy( "admins", - "(_args, { context }) => !!context.username ? 'ALLOW' : 'DENY'", + "(_args, { context }) => !!context.username ? 'PASS' : 'DENY'", ); g.expose( diff --git a/examples/typegraphs/rest.py b/examples/typegraphs/rest.py index 22595a3c8..1b3aff97d 100644 --- a/examples/typegraphs/rest.py +++ b/examples/typegraphs/rest.py @@ -51,7 +51,7 @@ def roadmap(g: Graph): admins = deno.policy( "admins", - "(_args, { context }) => !!context.username ? 'ALLOW' : 'DENY'", + "(_args, { context }) => !!context.username ? 'PASS' : 'DENY'", ) g.expose( diff --git a/examples/typegraphs/rest.ts b/examples/typegraphs/rest.ts index 1f3d6cd82..ec242e798 100644 --- a/examples/typegraphs/rest.ts +++ b/examples/typegraphs/rest.ts @@ -49,7 +49,7 @@ typegraph( const admins = deno.policy( "admins", - "(_args, { context }) => !!context.username ? 'ALLOW' : 'DENY'", + "(_args, { context }) => !!context.username ? 'PASS' : 'DENY'", ); g.expose( diff --git a/examples/typegraphs/roadmap-policies.py b/examples/typegraphs/roadmap-policies.py index 271e43818..dde6b51f9 100644 --- a/examples/typegraphs/roadmap-policies.py +++ b/examples/typegraphs/roadmap-policies.py @@ -56,7 +56,7 @@ def roadmap(g: Graph): # highlight-start admins = deno.policy( "admins", - "(_args, { context }) => !!context.username ? 'ALLOW' : 'DENY'", + "(_args, { context }) => !!context.username ? 'PASS' : 'DENY'", ) # highlight-end diff --git a/examples/typegraphs/roadmap-policies.ts b/examples/typegraphs/roadmap-policies.ts index d58ce5c07..458ebd9db 100644 --- a/examples/typegraphs/roadmap-policies.ts +++ b/examples/typegraphs/roadmap-policies.ts @@ -50,7 +50,7 @@ typegraph( const admins = deno.policy( "admins", - "(_args, { context }) => !!context.username ? 'ALLOW' : 'DENY'", + "(_args, { context }) => !!context.username ? 'PASS' : 'DENY'", ); g.expose( diff --git a/src/typegraph/core/src/lib.rs b/src/typegraph/core/src/lib.rs index 4c4c60ebb..8c33565b5 100644 --- a/src/typegraph/core/src/lib.rs +++ b/src/typegraph/core/src/lib.rs @@ -214,16 +214,16 @@ impl wit::core::Guest for Lib { .to_string(); let check = match check { - ContextCheck::NotNull => "value != null ? 'ALLOW' : 'DENY'".to_string(), + ContextCheck::NotNull => "value != null ? 'PASS' : 'DENY'".to_string(), ContextCheck::Value(val) => { format!( - "value === {} ? 'ALLOW' : 'DENY'", + "value === {} ? 'PASS' : 'DENY'", serde_json::to_string(&val).unwrap() ) } ContextCheck::Pattern(pattern) => { format!( - "new RegExp({}).test(value) ? 'ALLOW' : 'DENY' ", + "new RegExp({}).test(value) ? 'PASS' : 'DENY' ", serde_json::to_string(&pattern).unwrap() ) }