dnmfarrell/iamsim
GitHub: dnmfarrell/iamsim
一个基于 Prolog 的 AWS IAM 权限模拟模块,用于存储和评估身份策略与权限边界,帮助用户推理权限决策并生成修复建议。
Stars: 8 | Forks: 1
# AWS IAM 模拟器
一个用于存储 IAM policy 和 action 以模拟权限的 Prolog 模块。
有关项目背景和基本原理的更多信息,请参阅此[博客文章](https://blog.dnmfarrell.com/post/simulating-aws-iam-with-prolog/)。
需要 [Scryer-Prolog](https://scryer.pl/) 或类似的解释器。
## 限制
目前仅支持基于身份的 policy 和权限边界(permissions boundary)。但是,会话策略(session policy)(以及某些基于资源的 policy)可以建模为身份策略(identity policy),服务控制策略(service control policy)可以建模为权限边界。
假定每个数据库会话只有一个 principal。
不支持 [policy 条件](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html)。
仅包含 S3 action(欢迎提交 PR,参见 [iam/s3.pl](src/iam/s3.pl)。
## 谓词
### `policy_add(+Type,+Id,+Effect,+Action,+ArnStr, -Errs)`
向数据库添加 policy,其中:
* `Type` 是以下之一:`boundary` 或 `identity`。
* `Id` 是一个用于命名 policy 的字符串列表,例如 `"s3-foo-allow-all"`。
* `Effect` 是以下之一:`allow` 或 `deny`。
* `Action` 是字符串列表模式,例如 `"s3:PutObject"`、`"s3:*"` 或 `"*"`。
* `ArnStr` 是 AWS ARN 的字符串列表,例如 `"arn:aws:s3:::foo/bar"`。资源部分(最后一部分)可以是字符串模式,例如 `"fo?/*"`。
* `Errs` 是一个错误消息列表,当成功添加 policy 时,该列表为空。
### `can(+Action, +ArnStr, -Allowed, -Reasons, -Errs)`
评估 principal 是否被允许对该资源执行操作,其中:
* `Action` 是一个字符串列表,例如 `"s3:PutObject"`。
* `ArnStr` 是 AWS ARN 的字符串列表,例如 `"arn:aws:s3:::foo/bar"`。
* `Allowed` 是一个布尔值。
* `Reasons` 是一个解释评估推理过程的消息列表。
* `Errs` 是一个错误消息列表,当评估成功时,该列表为空。
### `all(-Actions, +ArnStr, -Err)`
返回 principal 可以对该资源执行的所有操作,其中:
* `Actions` 是允许的操作列表。
* `ArnStr` 是 AWS ARN 的字符串列表,例如 `"arn:aws:s3:::foo/bar"`。
* `Errs` 是一个错误消息列表,当评估成功时,该列表为空。
### `fix(+Action, +ArnStr, -Changes, -Errs)`
通过创建/删除 policy 来修复权限问题,其中:
* `Action` 是要授予的操作的字符串列表,例如 `"s3:PutObject"`。
* `ArnStr` 是 AWS ARN 的字符串列表,例如 `"arn:aws:s3:::foo/bar"`。
* `Changes` 是描述所执行操作的字符串列表。
* `Errs` 是一个错误消息列表,当修复成功时,该列表为空。
## 示例
```
$ scryer-prolog -f src/iam/sim.pl
?- % check if we can get foo/bar.csv
can("s3:GetObject", "arn:aws:s3:::foo/bar.csv", Allowed, Reasons, Errs).
Allowed = false, Reasons = ["\'Not explicitly all ..."].
?- % grant the permission
fix("s3:GetObject", "arn:aws:s3:::foo/bar.csv", Changelog, Errs).
Changelog = [changelog(add,policy(identity,"[s,\'3\',:,\'G\',e,t, ...",allow,"s3:GetObject","arn:aws:s3:::foo/ ..."))], Errs = []
; false.
?- % re-test
can("s3:GetObject", "arn:aws:s3:::foo/bar.csv", Allowed, Reasons, Errs).
Allowed = true, Reasons = ["\'Not explicitly den ...","\'Allowed by\' ident ..."].
?- % create a policy to grant all
policy_add(identity, "s3-foo-*", allow, "*", "arn:aws:s3:::foo/*", Errs).
Errs = [].
?- % What actions can we perform?
all(Actions, "arn:aws:s3:::foo/bar.csv", Errs).
; Actions = ["s3-object-lambda:Ab ...","s3-object-lambda:D ...","s3-object-lambda: ...","s3-object-lambda ...","s3-object-lambd ...","s3-object-lamb ...","s3-object-lam ...","s3-object-la ...","s3-object-l ...","s3-object- ...","s3-object ...","s3-objec ...","s3-obje ...","s3-obj ...","s3-ob ...","s3-o ...","s3- ...","s3 ...","s ...","s3-object-lambda:PutObjectLegalHold"|...], Errs = []
```
## 测试
```
$ bin/run-tests
+ scryer-prolog -f test/arn.pl
Running test "arn:aws:ec2:us-east-1:123456789012:foo/bar"
Running test "arn:aws:s3:::foo/bar"
+ scryer-prolog -f test/sim.pl
Running test "all-no-policies"
Running test "arn_match"
Running test "arn_parse"
Running test "service_match"
Running test "all-except-denied"
Running test "all-deny-beats-allow"
Running test "all-boundary-implicit-deny"
Running test "all-boundary-explicit-deny"
Running test "fix-no-policies"
Running test "fix-boundary-implicit-deny"
Running test "fix-explicit-deny"
```
标签:AWS IAM, Prolog, Streamlit, 权限模拟, 策略评估, 访问控制