Skip to content

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

@cabcookie

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions