Skip to content

Commit

Permalink
feat(iam): move OpenIdConnectProvider to native Cfn resource
Browse files Browse the repository at this point in the history
An L1 construct is now available for OpenID IAM identity providers.
This moves the previous L2 construct to use the L1 instead of the
existing custom resource, relieving the user of both the resource
overhead and the permissioning implications of the attached role.

BREAKING CHANGE: `OpenIdConnectProvider::fromOpenIdConnectProviderArn` -> `OpenIdConnectProvider::fromOidcProviderArn`
* **iam:** `OpenIdConnectProvider.openIdConnectProviderArn` -> `OpenIdConnectProvider::oidcProviderArn`
* **iam:** `OpenIdConnectProviderProps.thumbprints` now requires at least one entry
* **iam:** The custom resource behind `OpenIdConnectProvider` has been removed and is no longer available
  • Loading branch information
Adam Plumer committed Aug 12, 2021
1 parent 2e65e72 commit dfd0d34
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 691 deletions.
11 changes: 3 additions & 8 deletions packages/@aws-cdk/aws-iam/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -325,21 +325,16 @@ Identity Pools Developer Guide].
[Amazon Cognito Identity Pools Developer Guide]: https://docs.aws.amazon.com/cognito/latest/developerguide/open-id.html

The following examples defines an OpenID Connect provider. Two client IDs
(audiences) are will be able to send authentication requests to
https://openid/connect.
(audiences) will be able to send authentication requests to https://openid/connect.

```ts
const provider = new iam.OpenIdConnectProvider(this, 'MyProvider', {
url: 'https://openid/connect',
clientIds: [ 'myclient1', 'myclient2' ],
thumbprints: ['athumbprint'],
});
```

You can specify an optional list of `thumbprints`. If not specified, the
thumbprint of the root certificate authority (CA) will automatically be obtained
from the host as described
[here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html).

Once you define an OpenID connect provider, you can use it with AWS services
that expect an IAM OIDC provider. For example, when you define an [Amazon
Cognito identity
Expand All @@ -348,7 +343,7 @@ you can reference the provider's ARN as follows:

```ts
new cognito.CfnIdentityPool(this, 'IdentityPool', {
openIdConnectProviderArns: [myProvider.openIdConnectProviderArn],
openIdConnectProviderArns: [myProvider.oidcProviderArn],
// And the other properties for your identity pool
allowUnauthenticatedIdentities,
});
Expand Down
108 changes: 59 additions & 49 deletions packages/@aws-cdk/aws-iam/lib/oidc-provider.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import * as path from 'path';
import {
Arn,
CustomResource,
CustomResourceProvider,
CustomResourceProviderRuntime,
IResource,
Resource,
Token,
} from '@aws-cdk/core';
import { Arn, IResource, Resource, Token } from '@aws-cdk/core';
import { Construct } from 'constructs';

const RESOURCE_TYPE = 'Custom::AWSCDKOpenIdConnectProvider';
import { CfnOIDCProvider } from './iam.generated';

/**
* Represents an IAM OpenID Connect provider.
Expand All @@ -19,6 +9,13 @@ const RESOURCE_TYPE = 'Custom::AWSCDKOpenIdConnectProvider';
export interface IOpenIdConnectProvider extends IResource {
/**
* The Amazon Resource Name (ARN) of the IAM OpenID Connect provider.
*
* @attribute
*/
readonly oidcProviderArn: string;
/**
* The Amazon Resource Name (ARN) of the IAM OpenID Connect provider.
* @deprecated use `oidcProviderArn` instead
*/
readonly openIdConnectProviderArn: string;

Expand Down Expand Up @@ -79,12 +76,8 @@ export interface OpenIdConnectProviderProps {
* 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.
*
* @default - If no thumbprints are specified (an empty array or `undefined`),
* the thumbprint of the root certificate authority will be obtained 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[];
readonly thumbprints: string[];
}

/**
Expand All @@ -99,31 +92,68 @@ export interface OpenIdConnectProviderProps {
* @see http://openid.net/connect
* @see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc.html
*
* @resource AWS::CloudFormation::CustomResource
* @resource AWS::IAM::OIDCProvider
*/
export class OpenIdConnectProvider extends Resource implements IOpenIdConnectProvider {
/**
* Imports an Open ID connect provider from an ARN.
* @param scope The definition scope
* @param id ID of the construct
* @param openIdConnectProviderArn the ARN to import
* @deprecated use `OpenIdConnectProvider.fromOidcProviderArn` instead
*/
public static fromOpenIdConnectProviderArn(scope: Construct, id: string, openIdConnectProviderArn: string): IOpenIdConnectProvider {
const resourceName = Arn.extractResourceName(openIdConnectProviderArn, 'oidc-provider');

class Import extends Resource implements IOpenIdConnectProvider {
public readonly oidcProviderArn = openIdConnectProviderArn;
public readonly openIdConnectProviderArn = openIdConnectProviderArn;
public readonly openIdConnectProviderIssuer = resourceName;
}

return new Import(scope, id);
}

/**
* 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): IOpenIdConnectProvider {
const resourceName = Arn.extractResourceName(oidcProviderArn, 'oidc-provider');

class Import extends Resource implements IOpenIdConnectProvider {
public readonly oidcProviderArn = oidcProviderArn;
public readonly openIdConnectProviderArn = oidcProviderArn;
public readonly openIdConnectProviderIssuer = resourceName;
}

return new Import(scope, id);
}

/**
* The Amazon Resource Name (ARN) of the IAM OpenID Connect provider.
*
* @attribute
*/
public readonly openIdConnectProviderArn: string;
public readonly oidcProviderArn: string;

/**
* The Amazon Resource Name (ARN) of the IAM OpenID Connect provider.
*
* @attribute
* @deprecated use `oidcProviderArn` instead
*/
public get openIdConnectProviderArn(): string {
return this.oidcProviderArn;
}

/**
* The issuer of the OIDC provider.
*
* @attribute
*/
public readonly openIdConnectProviderIssuer: string;

/**
Expand All @@ -135,37 +165,17 @@ export class OpenIdConnectProvider extends Resource implements IOpenIdConnectPro
public constructor(scope: Construct, id: string, props: OpenIdConnectProviderProps) {
super(scope, id);

const resource = new CustomResource(this, 'Resource', {
resourceType: RESOURCE_TYPE,
serviceToken: this.getOrCreateProvider(),
properties: {
ClientIDList: props.clientIds,
ThumbprintList: props.thumbprints,
Url: props.url,
},
});

this.openIdConnectProviderArn = Token.asString(resource.ref);
this.openIdConnectProviderIssuer = Arn.extractResourceName(this.openIdConnectProviderArn, 'oidc-provider');
}
if (props.thumbprints.length < 1) {
throw new Error('Thumbprint list must contain at least one thumbprint.');
}

private getOrCreateProvider() {
return CustomResourceProvider.getOrCreate(this, RESOURCE_TYPE, {
codeDirectory: path.join(__dirname, 'oidc-provider'),
runtime: CustomResourceProviderRuntime.NODEJS_12_X,
policyStatements: [
{
Effect: 'Allow',
Resource: '*',
Action: [
'iam:CreateOpenIDConnectProvider',
'iam:DeleteOpenIDConnectProvider',
'iam:UpdateOpenIDConnectProviderThumbprint',
'iam:AddClientIDToOpenIDConnectProvider',
'iam:RemoveClientIDFromOpenIDConnectProvider',
],
},
],
const resource = new CfnOIDCProvider(this, 'Resource', {
clientIdList: props.clientIds,
thumbprintList: props.thumbprints,
url: props.url,
});

this.oidcProviderArn = Token.asString(resource.ref);
this.openIdConnectProviderIssuer = Arn.extractResourceName(this.oidcProviderArn, 'oidc-provider');
}
}
17 changes: 0 additions & 17 deletions packages/@aws-cdk/aws-iam/lib/oidc-provider/diff.ts

This file was deleted.

53 changes: 0 additions & 53 deletions packages/@aws-cdk/aws-iam/lib/oidc-provider/external.ts

This file was deleted.

89 changes: 0 additions & 89 deletions packages/@aws-cdk/aws-iam/lib/oidc-provider/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-iam/lib/principals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ export class OpenIdConnectPrincipal extends WebIdentityPrincipal {
* See [the IAM documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html).
*/
constructor(openIdConnectProvider: IOpenIdConnectProvider, conditions: Conditions = {}) {
super(openIdConnectProvider.openIdConnectProviderArn, conditions ?? {});
super(openIdConnectProvider.oidcProviderArn, conditions ?? {});
}

public get policyFragment(): PrincipalPolicyFragment {
Expand Down
Loading

0 comments on commit dfd0d34

Please sign in to comment.