Policy Templates

Policy Templates是包含占位符的策略, 占位符可以代表主体和资源。

之后,我们可以通过指定确切的主体和资源,基于Policy Template创建模板关联策略。模板关联策略是动态的,这意味着新策略会保持与其策略模板的关联。当我们更改Policy Template中的策略语句时,所有与该Template关联的策略将自动且立即使用新语句,用于从该时刻起做出的所有授权决策。

image-20260316150138809

创建Policy Template

Amazon Verified Permissions 页面上,单击左侧菜单中的 Policy templates,然后单击右上角的 Create policy template

image-20260316134827968

让我们使用 Task list viewer template 作为Policy Template描述,并使用以下内容:

permit (
    principal == ?principal,
    action in [
        TinyTodo::Action::"ReadList",
        TinyTodo::Action::"ListTasks",
        TinyTodo::Action::"ReadTask"
    ],
    resource == ?resource
);

单击 Create policy template

image-20260316134934129

让我们为列表编辑者创建另一个Policy Template。使用 Task list editor template 作为描述,并使用以下内容:

permit (
    principal == ?principal,
    action in [
        TinyTodo::Action::"ReadList",
        TinyTodo::Action::"UpdateList",
        TinyTodo::Action::"ListTasks",
        TinyTodo::Action::"CreateTask",
        TinyTodo::Action::"UpdateTask",
        TinyTodo::Action::"DeleteTask"
    ],
    resource == ?resource
);

单击 Create policy template

现在我们可以使用这些Policy Template为我们的应用程序创建策略。

从模板创建策略

让我们创建一个策略,使 bob 成为 alice 任务列表的查看者。

Amazon Verified Permissions 页面上,单击 Policies,单击右上角的 Create policy,然后选择 Create template-linked policy

image-20260316135115953

在下一页,选择 Task list viewer template 作为策略模板,然后单击 Next

image-20260316135142063

输入 TinyTodo::User::"bob" 作为主体,TinyTodo::List::"LIST#000001" 作为资源,然后单击 Create template-linked policy

image-20260316135253652

让我们还创建一个策略,使 alice 成为 bob 任务列表的编辑者。

单击右上角的 Create policy,然后选择 Create template-linked policy。选择 Task list editor template 作为策略模板,然后单击 Next

image-20260316135343513

输入 TinyTodo::User::"alice" 作为主体,TinyTodo::List::"LIST#000002" 作为资源,然后单击 Create template-linked policy

image-20260316135419493

最终,我们有两个策略,允许 bob 查看 alice 的列表,以及 alice 编辑 bob 的列表。

测试策略

Amazon Verified Permissions 页面上,单击左侧菜单中的 Test bench。切换到 JSON mode

首先,让我们测试允许 bob 查看 alice 列表(列表 LIST#000001)的策略。使用以下值:

字段 Entity Type Entity ID
Principal taking action TinyTodo::User bob
Resource TinyTodo::List LIST#000001
Action TinyTodo::Action ReadList

由于我们已添加 schema,实体类型已定义,已知操作支持自动补全。

image-20260316135552479

将 Entities 设置为 AVP format

使用以下根据我们的 schema 文件规范化的实体:

[
    {
        "identifier": {
            "entityType": "TinyTodo::User",
            "entityId": "alice"
        },
        "parents": [],
        "attributes": {}
    },
    {
        "identifier": {
            "entityType": "TinyTodo::User",
            "entityId": "bob"
        },
        "parents": [],
        "attributes": {}
    },
    {
        "identifier": {
            "entityType": "TinyTodo::User",
            "entityId": "charlie"
        },
        "parents": [],
        "attributes": {}
    },
    {
        "identifier": {
            "entityType": "TinyTodo::List",
            "entityId": "LIST#000001"
        },
        "parents": [],
        "attributes": {
            "listId": {
                "long": 1
            },
            "description": {
                "string": "Alice's daily tasks"
            },
            "name": {
                "string": "Alice's list"
            },
            "nextTaskId": {
                "long": 3
            },
            "owner": {
                "entityIdentifier": {
                    "entityType": "TinyTodo::User",
                    "entityId": "alice"
                }
            }
        }
    },
    {
        "identifier": {
            "entityType": "TinyTodo::List",
            "entityId": "LIST#000002"
        },
        "parents": [],
        "attributes": {
            "listId": {
                "long": 2
            },
            "description": {
                "string": "Bob's most important tasks"
            },
            "name": {
                "string": "Bob's tasks"
            },
            "nextTaskId": {
                "long": 3
            },
            "owner": {
                "entityIdentifier": {
                    "entityType": "TinyTodo::User",
                    "entityId": "bob"
                }
            }
        }
    },
    {
        "identifier": {
            "entityType": "TinyTodo::List",
            "entityId": "LIST#000003"
        },
        "parents": [],
        "attributes": {
            "listId": {
                "long": 3
            },
            "description": {
                "string": "Charlie's daily tasks"
            },
            "name": {
                "string": "Charlie's tasks"
            },
            "nextTaskId": {
                "long": 3
            },
            "owner": {
                "entityIdentifier": {
                    "entityType": "TinyTodo::User",
                    "entityId": "charlie"
                }
            }
        }
    },
    {
        "identifier": {
            "entityType": "TinyTodo::Task",
            "entityId": "TASK#000001"
        },
        "parents": [
            {
                "entityType": "TinyTodo::List",
                "entityId": "LIST#000001"
            }
        ],
        "attributes": {
            "listId": {
                "long": 1
            },
            "description": {
                "string": "Read emails in the morning"
            },
            "name": {
                "string": "Read emails"
            },
            "taskId": {
                "long": 1
            }
        }
    },
    {
        "identifier": {
            "entityType": "TinyTodo::Task",
            "entityId": "TASK#000002"
        },
        "parents": [
            {
                "entityType": "TinyTodo::List",
                "entityId": "LIST#000001"
            }
        ],
        "attributes": {
            "listId": {
                "long": 1
            },
            "description": {
                "string": "Send a daily report to the team at 5pm"
            },
            "name": {
                "string": "Send a daily report to the team"
            },
            "taskId": {
                "long": 2
            }
        }
    },
    {
        "identifier": {
            "entityType": "TinyTodo::Task",
            "entityId": "TASK#000001"
        },
        "parents": [
            {
                "entityType": "TinyTodo::List",
                "entityId": "LIST#000002"
            }
        ],
        "attributes": {
            "listId": {
                "long": 2
            },
            "description": {
                "string": "Attend the daily standup meeting at 9am"
            },
            "name": {
                "string": "Attend the daily standup meeting"
            },
            "taskId": {
                "long": 1
            }
        }
    },
    {
        "identifier": {
            "entityType": "TinyTodo::Task",
            "entityId": "TASK#000002"
        },
        "parents": [
            {
                "entityType": "TinyTodo::List",
                "entityId": "LIST#000002"
            }
        ],
        "attributes": {
            "listId": {
                "long": 2
            },
            "description": {
                "string": "Complete the time journal at 5pm"
            },
            "name": {
                "string": "Complete the time journal"
            },
            "taskId": {
                "long": 2
            }
        }
    },
    {
        "identifier": {
            "entityType": "TinyTodo::Task",
            "entityId": "TASK#000001"
        },
        "parents": [
            {
                "entityType": "TinyTodo::List",
                "entityId": "LIST#000003"
            }
        ],
        "attributes": {
            "listId": {
                "long": 3
            },
            "description": {
                "string": "Review new pull requests at 10am"
            },
            "name": {
                "string": "Review new pull requests"
            },
            "taskId": {
                "long": 1
            }
        }
    },
    {
        "identifier": {
            "entityType": "TinyTodo::Task",
            "entityId": "TASK#000002"
        },
        "parents": [
            {
                "entityType": "TinyTodo::List",
                "entityId": "LIST#000003"
            }
        ],
        "attributes": {
            "listId": {
                "long": 3
            },
            "description": {
                "string": "Check the team's KPIs at 5pm"
            },
            "name": {
                "string": "Check the team's KPIs"
            },
            "taskId": {
                "long": 2
            }
        }
    }
]

单击 Simulate request。请注意,结果为 Decision: Allow,因为我们的查看者策略已满足条件。

image-20260316135751604

但是,如果 bob 尝试读取 charlie 的列表(列表 LIST#000003),结果仍然是 Decision: Deny

image-20260316135809903

让我们还检查 alice 是否可以编辑 bob 的列表(列表 LIST#000002)。输入以下值:

字段 实体类型 实体 ID
Principal taking action TinyTodo::User alice
Resource TinyTodo::List LIST#000002
Action TinyTodo::Action UpdateList

image-20260316135836946

如我们所见,结果为 Decision: Allow,因为我们的编辑者策略已满足条件。

image-20260316135850822

但是,如果 alice 尝试编辑 charlie 的列表(列表 LIST#000003),结果仍然是 Decision: Deny

image-20260316135905695

编辑Policy Template

使用Policy Template的好处之一是,当我们更新模板时,所有模板关联策略都会自动更新。

首先,让我们从 Task list viewer template 策略模板中删除 TinyTodo::Action::"ReadTask" 操作。选择该模板并单击 Edit

image-20260316145845209

然后,从 Actions 中删除 TinyTodo::Action::"ReadTask" 操作,并单击 Update policy template

现在让我们检查从 Task list viewer template 策略模板创建的策略是否已更新。单击左侧导航窗格中的 Policies,然后单击我们为 bob 创建的策略。

image-20260316145907913

如我们所见,TinyTodo::Action::"ReadTask" 操作已从策略中删除。