Skip to content

Add allow.throughRelation() to the schema builder API #696

Description

@cabcookie

Package version

@aws-amplify/data-schema@1.x (latest)

Describe the feature

This is the data-schema companion to aws-amplify/amplify-category-api#3447, which proposes a throughRelation authorization strategy where child models inherit permissions from a parent model via a belongsTo relationship — eliminating the need to duplicate owner/editor/viewer arrays on every child record.

The data-schema package needs a new allow.throughRelation() builder method:

Document: a.model({
    name: a.string().required(),
    blocks: a.hasMany("DocumentBlock", "documentId"),
    editors: a.string().array(),
    viewers: a.string().array(),
  })
  .authorization((allow) => [
    allow.owner(),
    allow.ownersDefinedIn("editors").to(["read", "update", "create", "delete"]),
    allow.ownersDefinedIn("viewers").to(["read"]),
  ]),

DocumentBlock: a.model({
    content: a.string(),
    documentId: a.id().required(),
    document: a.belongsTo("Document", "documentId"),
  })
  .authorization((allow) => [
    allow.throughRelation("document"),  // inherits Document's auth rules
  ]),

Two changes needed:

  1. Authorization.ts — Add throughRelation(relationField: string) to the allow object, storing { strategy: "throughRelation", relationField } in [__data]
  2. SchemaProcessor.ts — In calculateAuth(), emit @auth(rules: [{ allow: throughRelation, throughRelation: "document" }]) in the SDL output so the auth transformer in amplify-category-api can consume it

This is additive — no existing builder methods or types change.

Use case

In collaborative applications (document editors, project management tools, shared notebooks), authorization is defined on a parent record and child records should inherit those permissions. Today, every child model must duplicate ownersDefinedIn arrays and keep them in sync via a Lambda cascade — which is fragile, expensive, and creates race conditions.

With throughRelation, permissions are defined once on the parent model. Child models reference the parent via a belongsTo field and the generated AppSync resolvers check the parent's permission fields at runtime. Adding a new role to the parent (e.g., allow.ownersDefinedIn("commenters").to(["read", "create"])) automatically applies to all child models on the next deploy — zero changes to child models.

See aws-amplify/amplify-category-api#3447 for the full proposal including all 7 use cases, resolver behavior, alternatives considered, and implementation details.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions