Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create REST API using CLI with both IAM and API key authorization #13454

Closed
funes79 opened this issue Dec 6, 2023 · 9 comments
Closed

Create REST API using CLI with both IAM and API key authorization #13454

funes79 opened this issue Dec 6, 2023 · 9 comments
Labels
api-rest Issues tied to REST APIs override Issues related to resource override CDK functionality pending-response Issue is pending response from the issue author pending-triage Issue is pending triage question General question

Comments

@funes79
Copy link

funes79 commented Dec 6, 2023

Amplify CLI Version

12.8.2

Question

Is it possible to setup a REST API using amplify cli so that it will be using IAM and also API key authentication? I would like to use IAM for Cognito role, but API key for external app. Thanks

@funes79 funes79 added pending-triage Issue is pending triage question General question labels Dec 6, 2023
@ykethan
Copy link
Member

ykethan commented Dec 6, 2023

Hey @funes79, thank you for reaching out. We can utilize the override functionality on the REST API resource to add the authorizations such as API key. Please refer to #13156 providing an example on this and REST API override documentation

@funes79
Copy link
Author

funes79 commented Dec 6, 2023

thanks for the response. The discords links are unfortunately not showing any content. I understand the concept, that first the amplify override api needs to be called. But then I am bit lost, the code fragments do not really add up.

  • Where do I define and store the value for the API key? Or does it create and auto generate the API key?
  • The code resources.restApi.apiKeySourceType = "HEADER"; suggests that it is overriding the IAM to API key authorization. What I would like to achieve is a combination - i.e. let Cognito authGroup access the API, but also provide a path to AWS SecretsManager where the API key value is stored.
  • Is there a documentation or guide how to put things together? I.e. create a API key, create a Usage plan and assign to all methods in the API?

@ykethan
Copy link
Member

ykethan commented Dec 6, 2023

Hey @funes79, Sure. Modified the override CDK example to show both the IAM and API key auth on the routes.

// This file is used to override the REST API resources configuration
import {
  AmplifyApiRestResourceStackTemplate,
  AmplifyProjectInfo,
} from "@aws-amplify/cli-extensibility-helper";

export function override(
  resources: AmplifyApiRestResourceStackTemplate,
  amplifyProjectInfo: AmplifyProjectInfo
) {
  resources.restApi.apiKeySourceType = "HEADER";
  resources.restApi.body.securityDefinitions = {
    ...resources.restApi.body.securityDefinitions,
    "use-api-key-in-header": {
      type: "apiKey",
      name: "x-api-key",
      in: "header",
      "x-amazon-apigateway-api-key-source": "HEADER",
    },
    AWS_IAM: {
      type: "apiKey",
      name: "authorization",
      in: "header",
      "x-amazon-apigateway-authtype": "awsSigv4",
    },
  };
  const custSecurityRules = [{ "use-api-key-in-header": [], AWS_IAM: [] }];
  Object.values(resources.restApi.body.paths).forEach((path: any) => {
    path.options.security = custSecurityRules;
    path["x-amazon-apigateway-any-method"].security = custSecurityRules;
  });
}

The sample example currently defines a securityDefinition with both api key as header and IAM auth to all the api paths . If you want to have some paths use only the API key, you'll need to define separate security rules for those paths.

Screenshot 2023-12-06 at 11 52 29 AM

resources.restApi.apiKeySourceType = "HEADER"; should allow passing in the API key as X-API-key header for the request, for example when providing a API key to your users. Documentation

The API keys are managed on the AWS API gateway console, I understand you would like to use AWS SecretsManager for the key management. I am not aware on a direct integration with API gateway to allow this, but you should be able to use a Lambda authorizer that calls the secrets manager and authorizes the request.

@ykethan ykethan added the pending-response Issue is pending response from the issue author label Dec 6, 2023
@funes79
Copy link
Author

funes79 commented Dec 10, 2023 via email

@github-actions github-actions bot removed the pending-response Issue is pending response from the issue author label Dec 10, 2023
@ykethan
Copy link
Member

ykethan commented Dec 11, 2023

Hey @funes79, the example adds both IAM and api key to the paths. Let me further clarify,

// following defines the api expects the request to have a header with api key
resources.restApi.apiKeySourceType = "HEADER";
// the following defines a security schema/definition for the api to allow api key and iam path
  resources.restApi.body.securityDefinitions = {
    ...resources.restApi.body.securityDefinitions,
    "use-api-key-in-header": {
      type: "apiKey",
      name: "x-api-key",
      in: "header",
      "x-amazon-apigateway-api-key-source": "HEADER",
    },
    AWS_IAM: {
      type: "apiKey",
      name: "authorization",
      in: "header",
      "x-amazon-apigateway-authtype": "awsSigv4",
    },
  };
// following are rules we can use to define on a api paths
  const apikeySecurityRules = [{ "use-api-key-in-header": [] }];
  const iamSecurityRules = [{ AWS_IAM: [] }];

// example on adding the api key rule to the `/items` path with `options` type method 
resources.restApi.body.paths["/items"].options.security = apikeySecurityRules;

// example on adding the api key rule to the `/items` path with `any` type method 
resources.restApi.body.paths["/items"]["x-amazon-apigateway-any-method"].security = apikeySecurityRules;

// similarly we can also add a iam auth rule to a different path
resources.restApi.body.paths["/abc"].options.security = iamSecurityRules;

Depending on your use case and the paths we can modify the auth type you would like to use on a path and method.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body

Hope this clarifies the example

@ykethan ykethan added api-rest Issues tied to REST APIs pending-response Issue is pending response from the issue author override Issues related to resource override CDK functionality labels Dec 11, 2023
@funes79
Copy link
Author

funes79 commented Dec 12, 2023

Yes, thanks for the clarification. I know that using overrides we can define on different paths or methods, IAM, API, or IAM + API. My question was more about if it is possible to have IAM + API key where API Gateway would do logical OR - so either it finds IAM access tokens in authorization in headers or the x-api-key in headers. Because my testing shows that if I enable both IAM and API (your first code you suggested) then I am not able to access the API using only IAM authorization (i.e. the standard API graphql access stops working from Amplify).

So my understanding is that API gateway enforces both accesses in the same time. If it is correct, then the question is how should I add additional api key on the calls generated from the nextjs client. But also, it does not really makes sense, right? If it checks both authorization in the same time. I hoped that it will be either that or that, so that one endpoint can be accessed using both authorization methods.

@github-actions github-actions bot removed the pending-response Issue is pending response from the issue author label Dec 12, 2023
@ykethan
Copy link
Member

ykethan commented Dec 12, 2023

@funes79 thank you for the information. I do not believe API gateway currently supports an or condition on the Authorization methods, once added the method becomes required. But we can utilize a Lambda function as Authorization to create a custom authorization logic. Lambda authorizer documentation
To note: The API gateway team does not recommend using API key as a authorization or authentication but intended to be used with methods such as IAM auth and usage plans. Please refer to best practices documentation providing this information.
When making a request from the client ensure to include the API Key in a header then send the signed request for the IAM auth.
IAM authorization
Signing AWS API request

@ykethan ykethan added the pending-response Issue is pending response from the issue author label Dec 12, 2023
@josefaidt
Copy link
Contributor

Closing due to inactivity

@josefaidt josefaidt closed this as not planned Won't fix, can't repro, duplicate, stale Feb 2, 2024
Copy link

github-actions bot commented Feb 2, 2024

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-rest Issues tied to REST APIs override Issues related to resource override CDK functionality pending-response Issue is pending response from the issue author pending-triage Issue is pending triage question General question
Projects
None yet
Development

No branches or pull requests

3 participants