Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated Apr 19, 2024

Per-user/per-owner data access

The owner authorization strategy restricts operations on a record to only the record's owner. When configured, the owner field will automatically be added and populated with the identity of the created user. The API will authorize against the owner field to allow or deny operations.

Add per-user/per-owner authorization rule

You can use the owner authorization strategy to restrict a record's access to a specific user. When owner authorization is configured, only the record's owner is allowed the specified operations.

amplify/data/resource.ts
1// The "owner" of a Todo is allowed to create, read, update, and delete their own todos
2const schema = a.schema({
3 Todo: a
4 .model({
5 content: a.string(),
6 })
7 .authorization(allow => [allow.owner()]),
8});
amplify/data/resource.ts
1// The "owner" of a Todo record is only allowed to create, read, and update it.
2// The "owner" of a Todo record is denied to delete it.
3const schema = a.schema({
4 Todo: a
5 .model({
6 content: a.string(),
7 })
8 .authorization(allow => [allow.owner().to(['create', 'read', 'update'])]),
9});

In your application, you can perform CRUD operations against the model using client.models.<model-name> with the userPool auth mode.

1import { generateClient } from 'aws-amplify/data';
2import type { Schema } from '../amplify/data/resource'; // Path to your backend resource definition
3
4const client = generateClient<Schema>();
5
6const { errors, data: newTodo } = await client.models.Todo.create(
7 {
8 content: 'My new todo',
9 },
13);

Behind the scenes, Amplify will automatically add a owner: a.string() field to each record which contains the record owner's identity information upon record creation.

By default, the Cognito user pool's user information is populated into the owner field. The value saved includes sub and username in the format <sub>::<username>. The API will authorize against the full value of <sub>::<username> or sub / username separately and return username. You can alternatively configure OpenID Connect as an authorization provider.

By default, owners can reassign the owner of their existing record to another user.

To prevent an owner from reassigning their record to another user, protect the owner field (by default owner: String) with a field-level authorization rule. For example, in a social media app, you would want to prevent Alice from being able to reassign Alice's Post to Bob.

1const schema = a.schema({
2 Todo: a
3 .model({
4 content: a.string(),
5 owner: a.string().authorization(allow => [allow.owner().to(['read', 'delete'])]),
6 })
7 .authorization(allow => [allow.owner()]),
8});

Customize the owner field

You can override the owner field to your own preferred field, by specifying a custom ownerField in the authorization rule.

1const schema = a.schema({
2 Todo: a
3 .model({
4 content: a.string(),
5 author: a.string(), // record owner information now stored in "author" field
6 })
7 .authorization(allow => [allow.ownerDefinedIn('author')]),
8});