Amplify-cli: @auth directive with IAM

Created on 1 Feb 2019  路  8Comments  路  Source: aws-amplify/amplify-cli

Is there a way to use @auth(rules: [{ allow: owner }]) transform if the GraphQL authentication type is set to IAM? Looks like the @auth transform only works when the GraphQL authentication type is set to cognito user pool.

I'd like to use the @auth feature, but my application requires backend mutations via lambda. From what I read, I don't think I can use GraphQL api from lambda unless I set my authentication to IAM.

What's the best practice when you want to use @auth transform, also want to make updates to your GraphQL backend via lambda?

feature-request graphql-transformer

Most helpful comment

From a lambda, if you use the aws-amplify package and use Auth.login() with valid credentials (i.e a service account that you create), you can call the graphql endpoint, with the cognito pool setup.

By-passing the graphQL endpoint is bad in most cases because you loose validations and subscriptions.

I think the issue here is that with the AWS_IAM setup in AppSync, the @model directive doesn't generate resolvers that are valid (because the $context.identity is different with AWS_IAM)

All 8 comments

At this point @auth is only valid for Cognito User Pools but we're looking at IAM in the future. I've tagged this as a feature request.

I am also using IAM. One benefit of using it is that you can have auth and unauth users, as described here.
When you implement @auth for IAM, it would then be great if you can also automate migration of user data from the unauth state to the auth state.
Thanks a lot !

I might be misunderstanding this issue, but is the following possible with the current Amplify package?

@undefobj Is it possible to use Cognito Pools and the @auth directive, but also to update data in the backend via lambda? Is it possible to update the backend by accessing the GraphQL endpoint directly? Is it possible to update the backend by updating the DynamoDB items directly?

For instance:

Let a BookReviewPost model be defined as such:

type BookReviewPost @model
    @auth(rules: [
      { allow: owner, mutations: [create], queries: [get, list] },
      # Admin users can access any operation.
      { allow: groups, groups: ["Admin"] }
    ])
  {
    id: ID!
    status: String!
    review: String!
  }

John the User makes a BookReviewPost using amplify API (type: graphql) and there is a backend approval process for all Book Reviews. Thus, the initial BookReviewPost object has status = "PENDING_APPROVAL" (let's pretend that the graphql transform hardcodes status to PENDING_APPROVAL in the backend so that John the User can't get sneaky )

Then, Jill the Reviewer (who is in the Admin cognito group) can review the BookReviewPost in her Web Admin Dashboard by querying the data. If she approves the post, she can update the status field to APPROVED using the Amplify.API package.

I believe that all of the above is completely possible and is how the system is designed.

Now, Jill the Reviewer is actually an asynchronous lambda function who is checking for certain keywords or sentiment or something:

  1. Would a Lambda function be capable of querying the Amplify.API package, reading the data, and updating the status on John the User's BookReviewPost?
  2. If it can't use that Amplify.API package, would it be able to access the GraphQL endpoint directly?
  3. If it can't use the GraphQL endpoint, could it alter the DynamoDB item directly/safely?

From a lambda, if you use the aws-amplify package and use Auth.login() with valid credentials (i.e a service account that you create), you can call the graphql endpoint, with the cognito pool setup.

By-passing the graphQL endpoint is bad in most cases because you loose validations and subscriptions.

I think the issue here is that with the AWS_IAM setup in AppSync, the @model directive doesn't generate resolvers that are valid (because the $context.identity is different with AWS_IAM)

Ah, okay that makes sense. I linked this issue in the auth directive RFC, could amplify create an IAM role and generate the resolvers such that $context.identity is overriden if the correct IAM role is calling the resolver?

@rohitspujari Had you considered the approach that @vparpoil suggests? Creating a service account that your lambda function logs into?

@ajhool @vparpoil Re: creating a Service Account for the lambda to log into and invoke AppSync queries and mutations, are there any best practices or recommendations around doing so? More importantly, any no-no's in order to avoid security issues?

@kwhitejr

The usual security issues... create least-privileged users who only have privileges to do what they need to do. I just use a user in an "Admin" cognito group, but I might create more fine-grained service groups with more constrained access.

Here's how I store/retrieve passwords for login.

import { SecretsManager } from 'aws-sdk';

interface IServiceCreds {
  username: string;
  pass: string;
}

/**
 * TODO: Inject ssm param names so we can use different ones for dev/test/prod, etc
 */
export const getServiceCreds = async (): Promise<IServiceCreds> => {
  const secretsManager = new SecretsManager({region: 'us-east-1'});
  const user = await secretsManager.getSecretValue({ SecretId: 'nds-service-user-dev' }).promise();

  if (!user || !user.SecretString) {
    throw new Error('Secret not found')
  }

  return JSON.parse(user.SecretString!);
}
...
    // WARNING: NEVER LOG
    const creds = await getServiceCreds();
    // WARNING: NEVER LOG
    await Auth.signIn(creds.username, creds.pass);
    // WARNING: NEVER LOG

We launched multi-auth support for AppSync API (which included public APIs - with API Keys + IAM) as a part of our CLI version 3.8+.
Please take a look at our documentation around it out here for more info - https://aws-amplify.github.io/docs/cli-toolchain/graphql#public-authorization

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rehos picture rehos  路  3Comments

YikSanChan picture YikSanChan  路  3Comments

onlybakam picture onlybakam  路  3Comments

nicksmithr picture nicksmithr  路  3Comments

gabriel-wilkes picture gabriel-wilkes  路  3Comments