Skip to content

Commit c82b385

Browse files
fix: authorizeBasic must match unconstrained policies
A permit(principal, action, resource) policy with no == constraints should match all requests (Cedar semantics). The string-match fallback was only matching policies containing the exact resource ID string, causing permit-all to never match.
1 parent 689c220 commit c82b385

File tree

3 files changed

+16
-5
lines changed

3 files changed

+16
-5
lines changed

openclaw.plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"id": "carapace",
33
"name": "Carapace",
44
"description": "Cedar policy enforcement for agent tool access via before_tool_call hook. Your agent's exoskeleton.",
5-
"version": "1.0.3",
5+
"version": "1.0.4",
66
"configSchema": {
77
"type": "object",
88
"additionalProperties": true,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@clawdreyhepburn/carapace",
3-
"version": "1.0.3",
3+
"version": "1.0.4",
44
"description": "Cedar policy enforcement for agent tool access via OpenClaw's before_tool_call hook.",
55
"license": "Apache-2.0",
66
"type": "module",

src/cedar-engine-cedarling.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,10 +627,21 @@ export class CedarlingEngine {
627627
let hasForbid = false;
628628
const reasons: string[] = [];
629629

630+
const principalId = request.principal;
631+
const actionId = request.action;
632+
const resourceId = request.resource;
633+
630634
for (const [id, policy] of this.policies) {
631-
// Simple: check if resource appears in the policy
632-
const resourceId = request.resource.replace(/.*::"/g, "").replace(/"$/, "");
633-
if (!policy.raw.includes(`"${resourceId}"`)) continue;
635+
// Parse constraints from raw policy text
636+
const hasPrincipalConstraint = /principal\s*==/.test(policy.raw);
637+
const hasActionConstraint = /action\s*==/.test(policy.raw);
638+
const hasResourceConstraint = /resource\s*==/.test(policy.raw);
639+
640+
// Check if this policy matches the request
641+
// Unconstrained fields match everything (Cedar semantics)
642+
if (hasPrincipalConstraint && !policy.raw.includes(principalId)) continue;
643+
if (hasActionConstraint && !policy.raw.includes(actionId)) continue;
644+
if (hasResourceConstraint && !policy.raw.includes(resourceId)) continue;
634645

635646
if (policy.effect === "forbid") {
636647
hasForbid = true;

0 commit comments

Comments
 (0)