@cdklabs/cdk-verified-permissions

中文文档
0.3.5发布于 2026/06/19Apache-2.0TypeScriptCommonJS构建来源已验证近 30 天下载 5.1万

L2 AWS CDK Constructs for Amazon Verified Permissions

原始使用文档
文档目录6 节
  1. Policy Store
  2. Schemas
  3. Identity Source
  4. Policy
  5. Policy Store Alias
  6. Policy Template

Amazon Verified Permissions L2 CDK Construct

This repo contains the implementation of an L2 CDK Construct for Amazon Verified Permissions

Project Stability

This construct is still versioned with alpha/v0 major version and we could introduce breaking changes even without a major version bump. Our goal is to keep the API stable & backwards compatible as much as possible but we currently cannot guarantee that. Once we'll publish v1.0.0 the breaking changes will be introduced via major version bumps.

Getting Started

Policy Store

Define a Policy Store with defaults (No description, No schema & Validation Settings Mode set to OFF):

const test = new PolicyStore(scope, "PolicyStore");

Define a Policy Store without Schema definition (Validation Settings Mode must be set to OFF):

const validationSettingsOff = {
  mode: ValidationSettingsMode.OFF,
};
const test = new PolicyStore(scope, "PolicyStore", {
  validationSettings: validationSettingsOff,
});

Define a Policy Store with Description and Schema definition (a STRICT Validation Settings Mode is strongly suggested for Policy Stores with schemas):

const validationSettingsStrict = {
  mode: ValidationSettingsMode.STRICT,
};
const cedarJsonSchema = {
  PhotoApp: {
    entityTypes: {
      User: {},
      Photo: {},
    },
    actions: {
      viewPhoto: {
        appliesTo: {
          principalTypes: ["User"],
          resourceTypes: ["Photo"],
        },
      },
    },
  },
};
const cedarSchema = {
  cedarJson: JSON.stringify(cedarJsonSchema),
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  schema: cedarSchema,
  validationSettings: validationSettingsStrict,
  description: "PolicyStore description"
});

Define a Policy Store with Validation Settings to OFF and Deletion Protection enabled:

const validationSettingsOff = {
  mode: ValidationSettingsMode.OFF,
};
const test = new PolicyStore(scope, "PolicyStore", {
  validationSettings: validationSettingsOff,
  deletionProtection: DeletionProtectionMode.ENABLED
});

Define a Policy Store with AWS owned key encryption (default behavior):

const policyStore = new PolicyStore(scope, "PolicyStore", {
  validationSettings: {
    mode: ValidationSettingsMode.OFF,
  },
  encryptionSettings: {
    awsOwnedKey: true,
  },
});

Define a Policy Store with a customer-managed KMS key for encryption:

const key = new kms.Key(scope, "PolicyStoreKey", {
  description: "Key for Verified Permissions Policy Store encryption",
});

const policyStore = new PolicyStore(scope, "PolicyStore", {
  validationSettings: {
    mode: ValidationSettingsMode.OFF,
  },
  encryptionSettings: {
    customerManagedKey: {
      key,
    },
  },
});

Define a Policy Store with a customer-managed KMS key and encryption context:

const key = new kms.Key(scope, "PolicyStoreKey", {
  description: "Key for Verified Permissions Policy Store encryption",
});

const policyStore = new PolicyStore(scope, "PolicyStore", {
  validationSettings: {
    mode: ValidationSettingsMode.OFF,
  },
  encryptionSettings: {
    customerManagedKey: {
      key,
      encryptionContext: {
        "department": "security",
        "project": "verified-permissions",
      },
    },
  },
});

Schemas

If you want to have type safety when defining a schema, you can accomplish this only in typescript. Simply use the Schema type exported by the @cedar-policy/cedar-wasm.

You can also generate simple schemas using the static functions schemaFromOpenApiSpec or schemaFromRestApi in the PolicyStore construct. This functionality replicates what you can find in the AWS Verified Permissions console.

Generate a schema from an OpenAPI spec:

const validationSettingsStrict = {
  mode: ValidationSettingsMode.STRICT,
};
const cedarJsonSchema = PolicyStore.schemaFromOpenApiSpec(
  'path/to/swaggerfile.json',
  'UserGroup',
);
const cedarSchema = {
  cedarJson: JSON.stringify(cedarJsonSchema),
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  schema: cedarSchema,
  validationSettings: validationSettingsStrict,
  description: "Policy store with schema generated from API Gateway",
});

Generate a schema from a RestApi construct:

const validationSettingsStrict = {
  mode: ValidationSettingsMode.STRICT,
};
const cedarJsonSchema = PolicyStore.schemaFromRestApi(
  new RestApi(scope, "RestApi"),
  "UserGroup",
);
const cedarSchema = {
  cedarJson: JSON.stringify(cedarJsonSchema),
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  schema: cedarSchema,
  validationSettings: validationSettingsStrict,
  description: "Policy store with schema generated from RestApi construct",
});

Identity Source

Define Identity Source with Cognito Configuration and required properties:

const userPool = new UserPool(scope, "UserPool"); // Creating a new Cognito UserPool
const validationSettingsStrict = {
  mode: ValidationSettingsMode.STRICT,
};
const cedarJsonSchema = {
  PhotoApp: {
    entityTypes: {
      User: {},
      Photo: {},
    },
    actions: {
      viewPhoto: {
        appliesTo: {
          principalTypes: ["User"],
          resourceTypes: ["Photo"],
        },
      },
    },
  },
};
const cedarSchema = {
  cedarJson: JSON.stringify(cedarJsonSchema),
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  schema: cedarSchema,
  validationSettings: validationSettingsStrict,
});
new IdentitySource(scope, "IdentitySource", {
  configuration: {
    cognitoUserPoolConfiguration: {
      userPool: userPool,
    },
  },
  policyStore: policyStore
});

Define Identity Source with Cognito Configuration and all properties:

const validationSettingsStrict = {
  mode: ValidationSettingsMode.STRICT,
};
const cedarJsonSchema = {
  PhotoApp: {
    entityTypes: {
      User: {},
      Photo: {},
    },
    actions: {
      viewPhoto: {
        appliesTo: {
          principalTypes: ["User"],
          resourceTypes: ["Photo"],
        },
      },
    },
  },
};
const cedarSchema = {
  cedarJson: JSON.stringify(cedarJsonSchema),
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  schema: cedarSchema,
  validationSettings: validationSettingsStrict,
});
const cognitoGroupEntityType = 'test';
const userPool = new UserPool(scope, "UserPool"); // Creating a new Cognito UserPool
new IdentitySource(scope, "IdentitySource", {
  configuration: {
    cognitoUserPoolConfiguration: {
      clientIds: ["&ExampleCogClientId;"],
      userPool: userPool,
      groupConfiguration: {
        groupEntityType: cognitoGroupEntityType,
      },
    },
  },
  policyStore: policyStore,
  principalEntityType: "PETEXAMPLEabcdefg111111",
});

Define Identity Source with OIDC Configuration and Access Token selection config:

const validationSettingsStrict = {
  mode: ValidationSettingsMode.STRICT,
};
const cedarJsonSchema = {
  PhotoApp: {
    entityTypes: {
      User: {},
      Photo: {},
    },
    actions: {
      viewPhoto: {
        appliesTo: {
          principalTypes: ["User"],
          resourceTypes: ["Photo"],
        },
      },
    },
  },
};
const cedarSchema = {
  cedarJson: JSON.stringify(cedarJsonSchema),
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  schema: cedarSchema,
  validationSettings: validationSettingsStrict,
});
const issuer = 'https://iamanidp.com';
const principalIdClaim = 'sub';
const entityIdPrefix = 'prefix';
const groupClaim = 'group';
const groupEntityType = 'GroupType';
new IdentitySource(scope, 'IdentitySource', {
  configuration: {
    openIdConnectConfiguration: {
      issuer: issuer,
      entityIdPrefix: entityIdPrefix,
      groupConfiguration: {
        groupClaim: groupClaim,
        groupEntityType: groupEntityType,
      },
      accessTokenOnly: {
        audiences: ['testAudience'],
        principalIdClaim: principalIdClaim,
      },
    },
  },
  policyStore: policyStore,
  principalEntityType: 'TestType',
});

Define Identity Source with OIDC Configuration and Identity Token selection config:

const validationSettingsStrict = {
  mode: ValidationSettingsMode.STRICT,
};
const cedarJsonSchema = {
  PhotoApp: {
    entityTypes: {
      User: {},
      Photo: {},
    },
    actions: {
      viewPhoto: {
        appliesTo: {
          principalTypes: ["User"],
          resourceTypes: ["Photo"],
        },
      },
    },
  },
};
const cedarSchema = {
  cedarJson: JSON.stringify(cedarJsonSchema),
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  schema: cedarSchema,
  validationSettings: validationSettingsStrict,
});
const issuer = 'https://iamanidp.com';
const entityIdPrefix = 'prefix';
const groupClaim = 'group';
const groupEntityType = 'UserGroup';
const principalIdClaim = 'sub';
new IdentitySource(scope, 'IdentitySource', {
  configuration: {
    openIdConnectConfiguration: {
      issuer: issuer,
      entityIdPrefix: entityIdPrefix,
      groupConfiguration: {
        groupClaim: groupClaim,
        groupEntityType: groupEntityType,
      },
      identityTokenOnly: {
        clientIds: [],
        principalIdClaim: principalIdClaim,
      },
    },
  },
  policyStore: policyStore,
});

Policy

Load all the .cedar files in a given folder and define Policy objects for each of them. All policies will be associated with the same policy store. PLEASE NOTE: this method internally uses the Policy.fromFile so the same rules applies.

const validationSettingsStrict = {
  mode: ValidationSettingsMode.STRICT,
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  validationSettings: validationSettingsStrict,
});
policyStore.addPoliciesFromPath('/path/to/my-policies');

Define a Policy and add it to a specific Policy Store:

const statement = `permit(
    principal,
    action in [MyFirstApp::Action::"Read"],
    resource
) when {
    true
};`;

const description = "Test policy assigned to the test store";
const validationSettingsOff = {
  mode: ValidationSettingsMode.OFF,
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  validationSettings: validationSettingsOff,
});

// Create a policy and add it to the policy store
const policy = new Policy(scope, "MyTestPolicy", {
  definition: {
    static: {
      statement,
      description,
    },
  },
  policyStore: policyStore,
});

Define a policy with a template linked definition:

const validationSettingsOff = {
  mode: ValidationSettingsMode.OFF,
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  validationSettings: validationSettingsOff,
});
const policyTemplateStatement = `
permit (
  principal == ?principal,
  action in [TinyTodo::Action::"ReadList", TinyTodo::Action::"ListTasks"],
  resource == ?resource
);`;
const template = new PolicyTemplate(scope, "PolicyTemplate", {
  statement: policyTemplateStatement,
  policyStore: policyStore,
});

const policy = new Policy(scope, "MyTestPolicy", {
  definition: {
    templateLinked: {
      policyTemplate: template,
      principal: {
        entityId: "exampleId",
        entityType: "exampleType",
      },
      resource: {
        entityId: "exampleId",
        entityType: "exampleType",
      },
    },
  },
  policyStore: policyStore,
});

Define a Policy with a statement from file: PLEASE NOTE:

  • The Policy.fromFile static method supports multiple Cedar policies per file. Every Policy must follow the standard Cedar rules. This means that every Policy must be terminated with a ; char.
  • You can specify the id of the Policy directly inside the Policy file through Cedar Annotations, using the annotation @cdkId. The id defined in the annotation will have priority with respect to the one passed in the Policy.fromFile method. In case no annotation is defined, the id passed in the Policy.fromFile method will be used. Since the Policy.fromFile method supports multiple Cedar policies per file, it is strongly suggested to define policy ids through the annotation, in order to avoid having many Policy Constructs with the same id (which will result in a CDK runtime error).
  • You can specify the description of the policy directly inside the Policy file, using the annotation @cdkDescription. The description defined in the annotation will have priority with respect to the one passed in the properties object of the Policy.fromFile method.
const description = "Test policy assigned to the test store";
const validationSettingsOff = {
  mode: ValidationSettingsMode.OFF,
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  validationSettings: validationSettingsOff,
});

// Create a policy and add it to the policy store
const policyFromFileProps = {
  policyStore,
  path: '/path/to/policy-statement.cedar',
  description: 'the policy description',
};
const policy = Policy.fromFile(scope, "MyTestPolicy", policyFromFileProps);

Policy Store Alias

A Policy Store Alias provides an alternative identifier that you can use to reference a policy store in API operations. This operation is idempotent — if multiple requests are made with the same aliasName and policyStoreId, subsequent requests will be ignored.

Define a Policy Store Alias for an existing policy store:

const policyStore = new PolicyStore(scope, "PolicyStore", {
  validationSettings: {
    mode: ValidationSettingsMode.OFF,
  },
});

new PolicyStoreAlias(scope, "PolicyStoreAlias", {
  aliasName: "my-app-production",
  policyStore: policyStore,
});

Reference an existing Policy Store Alias:

const alias = PolicyStoreAlias.fromAliasName(
  scope,
  "ImportedAlias",
  "my-app-production",
);

Policy Template

Define a Policy Template referring to a Cedar Statement in local file:

const validationSettingsOff = {
  mode: ValidationSettingsMode.OFF,
};
const policyStore = new PolicyStore(scope, "PolicyStore", {
  validationSettings: validationSettingsOff,
});
const templateFromFileProps = {
  policyStore,
  path: '/path/to/template-statement.cedar',
  description: "Allows sharing photos in full access mode",
};
const template = PolicyTemplate.fromFile(scope, "PolicyTemplate", templateFromFileProps);

Notes

版本与发布记录

@cdklabs/cdk-verified-permissions 共发布 31 个版本,首次发布于 2024/02/06;过去 12 个月发布了 5 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.3.5latest2026/06/194 个月前
0.3.42026/06/194 个月前
0.3.32026/02/049 个月前
0.3.22026/02/039 个月前
0.3.12026/01/139 个月前
0.3.02025/08/191.2 年前

关于 @cdklabs/cdk-verified-permissions 的常见问题

@cdklabs/cdk-verified-permissions 是什么?

L2 AWS CDK Constructs for Amazon Verified Permissions

如何安装 @cdklabs/cdk-verified-permissions?

在项目目录运行 npm install @cdklabs/cdk-verified-permissions,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:aws-cdk-lib(^2.260.0)、constructs(^10.5.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@cdklabs/cdk-verified-permissions 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cdklabs/cdk-verified-permissions 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@cdklabs/cdk-verified-permissions 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >= 18.12.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@cdklabs/cdk-verified-permissions 可以商用吗?

@cdklabs/cdk-verified-permissions 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@cdklabs/cdk-verified-permissions 的下载量有多少?

根据 npm 官方下载统计,@cdklabs/cdk-verified-permissions 在 2026/10/10 – 2026/11/08 这 30 天内被下载 50,635 次,日均约 1,688 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cdklabs/cdk-verified-permissions 还在维护吗?

最新版本 0.3.5 发布于 2026/06/19(4 个月前);至今共发布 31 个版本,其中过去 12 个月发布了 5 个;首次发布于 2024/02/06。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。