GithubHelp home page GithubHelp logo

cdklabs / cdk-verified-permissions Goto Github PK

View Code? Open in Web Editor NEW
17.0 11.0 2.0 1.01 MB

Amazon Verified Permissions L2 CDK Constructs

License: Apache License 2.0

TypeScript 100.00%
amazon-verified-permissions aws cdk cdk-constructs typescript

cdk-verified-permissions's Introduction

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"
});

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.

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: You can specify the description of the policy directly inside the Policy file, using the annotation @cdkDescription

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 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

cdk-verified-permissions's People

Contributors

cdklabs-automation avatar joshkraft avatar reste85 avatar svenjaraether avatar swolebrain avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cdk-verified-permissions's Issues

addPoliciesFromPath() should custom descriptions rather than file path

Currently if you lever addPoliciesFromPath() from the Policy store the description on each policy is defaulted to the absolute file path. This is ugly and also opens up information about the system that deploys the policies.

Possibly a cedar annotation in the policy itself or even just the file name instead of the path might be better

Missing groupEntityType in IdentitySource

Many thanks for this library! Hope it gets merged into cdk master at some point.

The construct for IdentitySource is missing props to configure the group settings.

See https://docs.aws.amazon.com/verifiedpermissions/latest/apireference/API_CognitoUserPoolConfiguration.html groupConfiguration and https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-verifiedpermissions-identitysource-cognitogroupconfiguration.html

The construct currently supports setting principalEntityType but not group.

This is what the setting looks like in the console:
image

We need a prop to specify what entity type cognito groups are.

proposal: schemaFromRestApi Method

Hi team,

It would be great to be able to generate a schema based off of CloudFormation templates, rather than having to deploy the API, export a swagger spec, and then generate based off of that.

What do you think of a new method schemaFromCloudFormationTemplate()?. I am thinking it would work exactly like schemaFromOpenApiSpec(), just with a different source.

If this aligns with the project’s direction, I’d be happy to make a contribution.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.