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

Can't set field-level authorization in amplify gen2 #2786

Open
binarycombinatrix opened this issue Aug 18, 2024 · 3 comments
Open

Can't set field-level authorization in amplify gen2 #2786

binarycombinatrix opened this issue Aug 18, 2024 · 3 comments
Labels
Gen 2 question Further information is requested transferred

Comments

@binarycombinatrix
Copy link

binarycombinatrix commented Aug 18, 2024

Environment information

System:
  OS: Windows 10 10.0.19045
  CPU: (8) x64 Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz
  Memory: 1.06 GB / 7.86 GB
Binaries:
  Node: 20.16.0 - C:\Program Files\nodejs\node.EXE   
  Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD     
  npm: 10.8.1 - C:\Program Files\nodejs\npm.CMD      
  pnpm: undefined - undefined
NPM Packages:
  @aws-amplify/backend: 1.0.4
  @aws-amplify/backend-cli: 1.1.1
  aws-amplify: 6.5.0
  aws-cdk: 2.149.0
  aws-cdk-lib: 2.149.0
  typescript: 5.5.3
AWS environment variables:
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1
  AWS_STS_REGIONAL_ENDPOINTS = regional
No CDK environment variables

Description

Even after specifying field level authorization for all required fields, it says required fields missing field-level authorization rules: below is the schema file
amplify/data/resource.ts

import { type ClientSchema, a, defineData } from "@aws-amplify/backend";

const schema = a.schema({
  Comment: a.customType({
    content: a
      .string()
      .required()
      .authorization((allow) => [
        allow.publicApiKey().to(["read"]),
        allow.authenticated(),
      ]),
    username: a
      .string()
      .required()
      .authorization((allow) => [
        allow.publicApiKey().to(["read"]),
        allow.authenticated(),
      ]),
    dp: a
      .string()
      .required()
      .authorization((allow) => [
        allow.publicApiKey().to(["read"]),
        allow.authenticated(),
      ]),
    dn: a
      .string()
      .required()
      .authorization((allow) => [
        allow.publicApiKey().to(["read"]),
        allow.authenticated(),
      ]),
  }),
  Video: a
    .model({
      partitionKey: a
        .string()
        .required()
        .authorization((allow) => [
          allow.publicApiKey().to(["read"]),
          allow.owner(),
        ]),
      sortKey: a
        .string()
        .required()
        .authorization((allow) => [
          allow.publicApiKey().to(["read"]),
          allow.owner(),
        ]), ////video title or username   + uuidv1
      type: a
        .string()
        .required()
        .authorization((allow) => [
          allow.publicApiKey().to(["read"]),
          allow.owner(),
        ]), ///specify type to avoid confusion
      category: a.string(), /// category which is partition key for video entry
      debate: a.json().array(), ///debate of the video
      description: a.string(), ///channel or video description
      url: a.string(), ///video url
      thumbnail: a.string(), ///video thumbnail
      dp: a.string(), ///user dp can store in both cases,
      comment: a
        .ref("Comment")
        .array()
        .authorization((allow) => [
          allow.publicApiKey().to(["read"]),
          allow.authenticated(),
        ]), ///only in case of video
      dn: a.string(), //display name
      username: a.string(),
    })
    .identifier(["partitionKey", "sortKey"])
    .authorization((allow) => [
      // allow.publicApiKey(),
      allow.publicApiKey().to(["read"]),
      // Allow signed-in user to create, read, update,
      // and delete their __OWN__ posts.
      allow.owner(),
    ]),
});

export type Schema = ClientSchema<typeof schema>;

export const data = defineData({
  schema,
  authorizationModes: {
    defaultAuthorizationMode: "apiKey",
    // API Key is used for a.allow.public() rules
    apiKeyAuthorizationMode: {
      expiresInDays: 30,
    },
  },
});

The error from the terminal is as below:

Failed to instantiate data construct

Caused By: When using field-level authorization rules you need to add rules to all of the model's required fields with at least read permissions. Found model "Video" with required fields ["partitionKey","sortKey","type"] missing field-level authorization rules.\n\nFor more information visit https://docs.amplify.aws/ction-rules
@ykethan
Copy link
Member

ykethan commented Aug 19, 2024

Hey,👋 thanks for raising this! I'm going to transfer this over to our API repository for better assistance 🙂

@ykethan ykethan transferred this issue from aws-amplify/amplify-backend Aug 19, 2024
@AnilMaktala AnilMaktala added the question Further information is requested label Aug 21, 2024
@AnilMaktala
Copy link
Member

Hey @binarycombinatrix, When using field-level authorization, you must grant at least read permissions to the remaining fields. I've noticed that the category, debate, description, url, thumbnail, dp, dn, and username fields in the Video model are missing permissions. Please modify the fields as shown below and let me know if this resolves your issue.

Video: a
    .model({
      partitionKey: a
        .string()
        .required()
        .authorization((allow) => [
          allow.publicApiKey().to(["read"]),
          allow.owner(),
        ]),
      sortKey: a
        .string()
        .required()
        .authorization((allow) => [
          allow.publicApiKey().to(["read"]),
          allow.owner(),
        ]), ////video title or username   + uuidv1
      type: a
        .string()
        .required()
        .authorization((allow) => [
          allow.publicApiKey().to(["read"]),
          allow.owner(),
        ]), ///specify type to avoid confusion
      category: a
        .string()
        .authorization((allow) => [allow.publicApiKey().to(["read"])]),
      debate: a
        .json()
        .array()
        .authorization((allow) => [allow.publicApiKey().to(["read"])]), ///debate of the video
      description: a
        .string()
        .authorization((allow) => [allow.publicApiKey().to(["read"])]), ///channel or video description
      url: a
        .string()
        .authorization((allow) => [allow.publicApiKey().to(["read"])]), ///video url
      thumbnail: a
        .string()
        .authorization((allow) => [allow.publicApiKey().to(["read"])]), ///video thumbnail
      dp: a
        .string()
        .authorization((allow) => [allow.publicApiKey().to(["read"])]), ///user dp can store in both cases,
      comment: a
        .ref("Comment")
        .array()
        .authorization((allow) => [
          allow.publicApiKey().to(["read"]),
          allow.authenticated(),
        ]), ///only in case of video
      dn: a
        .string()
        .authorization((allow) => [allow.publicApiKey().to(["read"])]), //display name
      username: a
        .string()
        .authorization((allow) => [allow.publicApiKey().to(["read"])]),
    })
    .identifier(["partitionKey", "sortKey"])
    .authorization((allow) => [
      // allow.publicApiKey(),
      allow.publicApiKey().to(["read"]),
      // Allow signed-in user to create, read, update,
      // and delete their __OWN__ posts.
      allow.owner(),
    ]),

@binarycombinatrix
Copy link
Author

Hi @AnilMaktala did you try running your version? Those other fields are not required fields and so do not require field level auth, as the model level authorization applies to them and I added publicApi read to it already.

The error too says the issue is with required fields.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Gen 2 question Further information is requested transferred
Projects
None yet
Development

No branches or pull requests

3 participants