diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/integ.json new file mode 100644 index 0000000000000..e0551ce01556f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "36.0.0", + "testCases": { + "oidc-provider-native-integ-test/DefaultTest": { + "stacks": [ + "oidc-provider-native-integ-stack" + ], + "diffAssets": true, + "assertionStack": "oidc-provider-native-integ-test/DefaultTest/DeployAssert", + "assertionStackName": "oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/manifest.json new file mode 100644 index 0000000000000..2e54da92be6c4 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/manifest.json @@ -0,0 +1,143 @@ +{ + "version": "36.0.0", + "artifacts": { + "oidc-provider-native-integ-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "oidc-provider-native-integ-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "oidc-provider-native-integ-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "oidc-provider-native-integ-stack.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/e40bdaff510d57b730ef01d0b8b96de982cb3f99015cc6cdab2ba232174b610a.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "oidc-provider-native-integ-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "oidc-provider-native-integ-stack.assets" + ], + "metadata": { + "/oidc-provider-native-integ-stack/Provider/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Provider2281708E" + } + ], + "/oidc-provider-native-integ-stack/Minimal/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Minimal107EFE55" + } + ], + "/oidc-provider-native-integ-stack/Arn": [ + { + "type": "aws:cdk:logicalId", + "data": "Arn" + } + ], + "/oidc-provider-native-integ-stack/Issuer": [ + { + "type": "aws:cdk:logicalId", + "data": "Issuer" + } + ], + "/oidc-provider-native-integ-stack/MinimalArn": [ + { + "type": "aws:cdk:logicalId", + "data": "MinimalArn" + } + ], + "/oidc-provider-native-integ-stack/MinimalIssuer": [ + { + "type": "aws:cdk:logicalId", + "data": "MinimalIssuer" + } + ], + "/oidc-provider-native-integ-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/oidc-provider-native-integ-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "oidc-provider-native-integ-stack" + }, + "oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.assets" + ], + "metadata": { + "/oidc-provider-native-integ-test/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/oidc-provider-native-integ-test/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "oidc-provider-native-integ-test/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidc-provider-native-integ-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidc-provider-native-integ-stack.assets.json new file mode 100644 index 0000000000000..6d668870081fc --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidc-provider-native-integ-stack.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "e40bdaff510d57b730ef01d0b8b96de982cb3f99015cc6cdab2ba232174b610a": { + "source": { + "path": "oidc-provider-native-integ-stack.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "e40bdaff510d57b730ef01d0b8b96de982cb3f99015cc6cdab2ba232174b610a.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidc-provider-native-integ-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidc-provider-native-integ-stack.template.json new file mode 100644 index 0000000000000..cbdb5abedcd05 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidc-provider-native-integ-stack.template.json @@ -0,0 +1,103 @@ +{ + "Resources": { + "Provider2281708E": { + "Type": "AWS::IAM::OIDCProvider", + "Properties": { + "ClientIdList": [ + "foo", + "bar" + ], + "ThumbprintList": [ + "aa00aa1122aa00aa1122aa00aa1122aa00aa1122", + "aa00aa1122aa00aa1122aa00aa1122aa00aa1111" + ], + "Url": "https://oidc.eks.us-east-1.amazonaws.com/id/test1" + } + }, + "Minimal107EFE55": { + "Type": "AWS::IAM::OIDCProvider", + "Properties": { + "ThumbprintList": [ + "aa00aa1122aa00aa1122aa00aa1122aa00aa1122" + ], + "Url": "https://oidc.eks.us-east-1.amazonaws.com/id/test2" + } + } + }, + "Outputs": { + "Arn": { + "Value": { + "Ref": "Provider2281708E" + } + }, + "Issuer": { + "Value": { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + ":oidc-provider/", + { + "Ref": "Provider2281708E" + } + ] + } + ] + } + }, + "MinimalArn": { + "Value": { + "Ref": "Minimal107EFE55" + } + }, + "MinimalIssuer": { + "Value": { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + ":oidc-provider/", + { + "Ref": "Minimal107EFE55" + } + ] + } + ] + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.assets.json new file mode 100644 index 0000000000000..a3f32a017add7 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/oidcprovidernativeintegtestDefaultTestDeployAssert9F17FB34.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/tree.json new file mode 100644 index 0000000000000..2d4191aba2242 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.js.snapshot/tree.json @@ -0,0 +1,192 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "oidc-provider-native-integ-stack": { + "id": "oidc-provider-native-integ-stack", + "path": "oidc-provider-native-integ-stack", + "children": { + "Provider": { + "id": "Provider", + "path": "oidc-provider-native-integ-stack/Provider", + "children": { + "Resource": { + "id": "Resource", + "path": "oidc-provider-native-integ-stack/Provider/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::OIDCProvider", + "aws:cdk:cloudformation:props": { + "clientIdList": [ + "foo", + "bar" + ], + "thumbprintList": [ + "aa00aa1122aa00aa1122aa00aa1122aa00aa1122", + "aa00aa1122aa00aa1122aa00aa1122aa00aa1111" + ], + "url": "https://oidc.eks.us-east-1.amazonaws.com/id/test1" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnOIDCProvider", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.OIDCProvider", + "version": "0.0.0" + } + }, + "Minimal": { + "id": "Minimal", + "path": "oidc-provider-native-integ-stack/Minimal", + "children": { + "Resource": { + "id": "Resource", + "path": "oidc-provider-native-integ-stack/Minimal/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::OIDCProvider", + "aws:cdk:cloudformation:props": { + "thumbprintList": [ + "aa00aa1122aa00aa1122aa00aa1122aa00aa1122" + ], + "url": "https://oidc.eks.us-east-1.amazonaws.com/id/test2" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnOIDCProvider", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.OIDCProvider", + "version": "0.0.0" + } + }, + "Arn": { + "id": "Arn", + "path": "oidc-provider-native-integ-stack/Arn", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "Issuer": { + "id": "Issuer", + "path": "oidc-provider-native-integ-stack/Issuer", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "MinimalArn": { + "id": "MinimalArn", + "path": "oidc-provider-native-integ-stack/MinimalArn", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "MinimalIssuer": { + "id": "MinimalIssuer", + "path": "oidc-provider-native-integ-stack/MinimalIssuer", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "oidc-provider-native-integ-stack/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "oidc-provider-native-integ-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "oidc-provider-native-integ-test": { + "id": "oidc-provider-native-integ-test", + "path": "oidc-provider-native-integ-test", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "oidc-provider-native-integ-test/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "oidc-provider-native-integ-test/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "oidc-provider-native-integ-test/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "oidc-provider-native-integ-test/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "oidc-provider-native-integ-test/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.ts new file mode 100644 index 0000000000000..c536e10ef47b0 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.oidc-provider-native.ts @@ -0,0 +1,42 @@ +import { App, Stack, CfnOutput } from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as iam from 'aws-cdk-lib/aws-iam'; + +const app = new App(); +const stack = new Stack(app, 'oidc-provider-native-integ-stack'); + +const provider = new iam.OidcProvider(stack, 'Provider', { + oidcProviderName: 'MyProvider', + url: 'https://oidc.eks.us-east-1.amazonaws.com/id/test1', + clientIds: ['foo', 'bar'], + thumbprints: [ + 'aa00aa1122aa00aa1122aa00aa1122aa00aa1122', + 'aa00aa1122aa00aa1122aa00aa1122aa00aa1111', + ], +}); + +const minimal = new iam.OidcProvider(stack, 'Minimal', { + url: 'https://oidc.eks.us-east-1.amazonaws.com/id/test2', + thumbprints: ['aa00aa1122aa00aa1122aa00aa1122aa00aa1122'], +}); + +new CfnOutput(stack, 'Arn', { + value: `${provider.oidcProviderArn}`, +}); + +new CfnOutput(stack, 'Issuer', { + value: `${provider.oidcProviderIssuer}`, +}); + +new CfnOutput(stack, 'MinimalArn', { + value: `${minimal.oidcProviderArn}`, +}); + +new CfnOutput(stack, 'MinimalIssuer', { + value: `${minimal.oidcProviderIssuer}`, +}); + +new IntegTest(app, 'oidc-provider-native-integ-test', { + testCases: [stack], + diffAssets: true, +}); diff --git a/packages/aws-cdk-lib/aws-iam/lib/index.ts b/packages/aws-cdk-lib/aws-iam/lib/index.ts index 32908963a7e17..a3cdf891fe5c5 100644 --- a/packages/aws-cdk-lib/aws-iam/lib/index.ts +++ b/packages/aws-cdk-lib/aws-iam/lib/index.ts @@ -11,6 +11,7 @@ export * from './identity-base'; export * from './grant'; export * from './unknown-principal'; export * from './oidc-provider'; +export * from './oidc-provider-native'; export * from './permissions-boundary'; export * from './saml-provider'; export * from './access-key'; diff --git a/packages/aws-cdk-lib/aws-iam/lib/oidc-provider-native.ts b/packages/aws-cdk-lib/aws-iam/lib/oidc-provider-native.ts new file mode 100644 index 0000000000000..09b148228ffe0 --- /dev/null +++ b/packages/aws-cdk-lib/aws-iam/lib/oidc-provider-native.ts @@ -0,0 +1,179 @@ +import { Construct } from 'constructs'; +import { CfnOIDCProvider } from './iam.generated'; +import { Arn, IResource, Resource, Token } from '../../core'; + +/** + * Represents an IAM OpenID Connect provider. + * + */ +export interface IOidcProvider extends IResource { + /** + * The Amazon Resource Name (ARN) of the IAM OpenID Connect provider. + * + * @attribute + */ + readonly oidcProviderArn: string; + + /** + * The issuer for OIDC Provider + * + * @attribute + */ + readonly oidcProviderIssuer: string; +} + +/** + * Initialization properties for `OIDCProvider`. + */ +export interface OidcProviderProps { + /** + * The name of the OIDC Provider. + * + * @default - A name is automatically generated. + */ + readonly oidcProviderName?: string; + + /** + * The URL of the identity provider. The URL must begin with https:// and + * should correspond to the iss claim in the provider's OpenID Connect ID + * tokens. Per the OIDC standard, path components are allowed but query + * parameters are not. Typically the URL consists of only a hostname, like + * https://server.example.org or https://example.com. + * + * You cannot register the same provider multiple times in a single AWS + * account. If you try to submit a URL that has already been used for an + * OpenID Connect provider in the AWS account, you will get an error. + */ + readonly url: string; + + /** + * A list of client IDs (also known as audiences). When a mobile or web app + * registers with an OpenID Connect provider, they establish a value that + * identifies the application. (This is the value that's sent as the client_id + * parameter on OAuth requests.) + * + * You can register multiple client IDs with the same provider. For example, + * you might have multiple applications that use the same OIDC provider. You + * cannot register more than 100 client IDs with a single IAM OIDC provider. + * + * Client IDs are up to 255 characters long. + * + * @default - no clients are allowed + */ + readonly clientIds?: string[]; + + /** + * A list of server certificate thumbprints for the OpenID Connect (OIDC) + * identity provider's server certificates. + * + * Typically this list includes only one entry. However, IAM lets you have up + * to five thumbprints for an OIDC provider. This lets you maintain multiple + * thumbprints if the identity provider is rotating certificates. + * + * The server certificate thumbprint is the hex-encoded SHA-1 hash value of + * the X.509 certificate used by the domain where the OpenID Connect provider + * makes its keys available. It is always a 40-character string. + * + * You must provide at least one thumbprint when creating an IAM OIDC + * provider. For example, assume that the OIDC provider is server.example.com + * and the provider stores its keys at + * https://keys.server.example.com/openid-connect. In that case, the + * thumbprint string would be the hex-encoded SHA-1 hash value of the + * certificate used by https://keys.server.example.com. + * + * Obtain the thumbprint of the root certificate authority from the provider's + * server as described in https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html + */ + readonly thumbprints: string[]; +} + +/** + * IAM OIDC identity providers are entities in IAM that describe an external + * identity provider (IdP) service that supports the OpenID Connect (OIDC) + * standard, such as Google or Salesforce. You use an IAM OIDC identity provider + * when you want to establish trust between an OIDC-compatible IdP and your AWS + * account. This is useful when creating a mobile app or web application that + * requires access to AWS resources, but you don't want to create custom sign-in + * code or manage your own user identities. + * + * @see http://openid.net/connect + * @see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc.html + * + * @resource AWS::IAM::OIDCProvider + */ +export class OidcProvider extends Resource implements IOidcProvider { + /** + * Imports an Open ID connect provider from an ARN. + * @param scope The definition scope + * @param id ID of the construct + * @param oidcProviderArn the ARN to import + */ + public static fromOidcProviderArn( + scope: Construct, + id: string, + oidcProviderArn: string, + ): IOidcProvider { + const resourceName = Arn.extractResourceName( + oidcProviderArn, + 'oidc-provider', + ); + + class Import extends Resource implements IOidcProvider { + public readonly oidcProviderArn = oidcProviderArn; + public readonly oidcProviderIssuer = resourceName; + } + + return new Import(scope, id); + } + + /** + * The Amazon Resource Name (ARN) of the IAM OpenID Connect provider. + * + * @attribute + */ + public readonly oidcProviderArn: string; + + /** + * The issuer for OIDC Provider + * + * @attribute + */ + public readonly oidcProviderIssuer: string; + + /** + * The thumbprints configured for this provider. + * + * @attribute + */ + public readonly oidcProviderThumbprints: string; + + /** + * Defines an OpenID Connect provider. + * @param scope The definition scope + * @param id Construct ID + * @param props Initialization properties + */ + public constructor( + scope: Construct, + id: string, + props: OidcProviderProps, + ) { + super(scope, id, { + physicalName: props.oidcProviderName, + }); + + const resource = new CfnOIDCProvider(this, 'Resource', { + url: props.url, + clientIdList: props.clientIds, + thumbprintList: props.thumbprints, + }); + + this.oidcProviderArn = Token.asString(resource.ref); + this.oidcProviderIssuer = Arn.extractResourceName( + this.oidcProviderArn, + 'oidc-provider', + ); + + this.oidcProviderThumbprints = Token.asString(props.thumbprints); + } +} diff --git a/packages/aws-cdk-lib/aws-iam/lib/oidc-provider.ts b/packages/aws-cdk-lib/aws-iam/lib/oidc-provider.ts index b8c5494038a24..93f781f8ef2b7 100644 --- a/packages/aws-cdk-lib/aws-iam/lib/oidc-provider.ts +++ b/packages/aws-cdk-lib/aws-iam/lib/oidc-provider.ts @@ -98,6 +98,7 @@ export interface OpenIdConnectProviderProps { * @see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc.html * * @resource AWS::CloudFormation::CustomResource + * @deprecated Use { @link OidcProvider } instead. */ export class OpenIdConnectProvider extends Resource implements IOpenIdConnectProvider { /** diff --git a/packages/aws-cdk-lib/aws-iam/test/oidc-provider-native.test.ts b/packages/aws-cdk-lib/aws-iam/test/oidc-provider-native.test.ts new file mode 100644 index 0000000000000..eea152dc9d1b1 --- /dev/null +++ b/packages/aws-cdk-lib/aws-iam/test/oidc-provider-native.test.ts @@ -0,0 +1,115 @@ +import { Template } from '../../assertions'; +import { App, Stack, Token } from '../../core'; +import * as iam from '../lib'; + +const arnOfProvider = + 'arn:aws:iam::1234567:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/someid'; + +describe('OidcProvider resource', () => { + test('"OIDCProviderArn" resolves to the ref', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + const provider = new iam.OidcProvider(stack, 'MyProvider', { + url: 'https://openid-endpoint', + thumbprints: ['thumbprint'], + }); + + // THEN + expect(stack.resolve(provider.oidcProviderArn)).toStrictEqual({ + Ref: 'MyProvider730BA1C8', + }); + }); + + test('static fromOidcProviderArn can be used to import a provider', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + const provider = iam.OidcProvider.fromOidcProviderArn( + stack, + 'MyProvider', + arnOfProvider, + ); + + // THEN + expect(stack.resolve(provider.oidcProviderArn)).toStrictEqual( + arnOfProvider, + ); + }); + + test('thumbprint list and client ids can be specified', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new iam.OidcProvider(stack, 'MyProvider', { + url: 'https://my-url', + clientIds: ['client1', 'client2'], + thumbprints: ['thumb1'], + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::OIDCProvider', { + Url: 'https://my-url', + ClientIdList: ['client1', 'client2'], + ThumbprintList: ['thumb1'], + }); + }); +}); + +describe('OIDC issuer', () => { + test('extract issuer properly in the new provider', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + const provider = new iam.OidcProvider(stack, 'MyProvider', { + url: 'https://my-issuer', + thumbprints: ['thumb1'], + }); + + // THEN + expect(stack.resolve(provider.oidcProviderIssuer)).toStrictEqual({ + 'Fn::Select': [ + 1, + { 'Fn::Split': [':oidc-provider/', { Ref: 'MyProvider730BA1C8' }] }, + ], + }); + }); + + test('extract issuer properly in a literal imported provider', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + const provider = iam.OidcProvider.fromOidcProviderArn( + stack, + 'MyProvider', + arnOfProvider, + ); + + // THEN + expect(stack.resolve(provider.oidcProviderIssuer)).toStrictEqual( + 'oidc.eks.us-east-1.amazonaws.com/id/someid', + ); + }); + + test('extract issuer properly in a Token imported provider', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + const provider = iam.OidcProvider.fromOidcProviderArn( + stack, + 'MyProvider', + Token.asString({ Ref: 'ARN' }), + ); + + // THEN + expect(stack.resolve(provider.oidcProviderIssuer)).toStrictEqual({ + 'Fn::Select': [1, { 'Fn::Split': [':oidc-provider/', { Ref: 'ARN' }] }], + }); + }); +});