Casbinというアクセス制御のライブラリを試してみました。認証・認可をKeycloakというサービスを使うのではなく、プログラミングライブラリという形で簡単に実装できるものです。
https://casbin.org/
トップページを見ると、何に使うのか、関連しているプラットホームは、などなど、何となくイメージできそうです。
ここでは下記参考にGo言語で実装してみました。
またdockerによるマルチステージビルドも試した見ました。
(Go versionが古いとエラー。alpineだとNG)
https://future-architect.github.io/articles/20221004a/
https://qiita.com/come2ry/items/98b0bb70e29821b52ba0
main.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package main import ( "fmt" "log" "github.com/casbin/casbin/v2" "github.com/casbin/casbin/v2/model" fileadapter "github.com/casbin/casbin/v2/persist/file-adapter" ) func main() { modelParam, err := model.NewModelFromFile("model.conf") if err != nil { log.Fatalf("NewModelFromString: %s", err) } enforcer, err := casbin.NewEnforcer(modelParam, fileadapter.NewAdapter("policy.csv")) if err != nil { log.Fatalf("NewEnforcer: %s", err) } users := [][]any{ {"Alice", "data1", "read"}, {"Bob", "data1", "write"}, {"Charlie", "data2", "read"}, } for _, v := range users { ok, err := enforcer.Enforce(v...) if err != nil { log.Fatalf("enforce: %s", err) } fmt.Printf("%v: %v\n", v, ok) } } |
model.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [role_definition] g = _ , _ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act |
policy.csv
1 2 3 4 5 6 |
p, admin, data1, read p, admin, data2, read p, admin, data3, read p, Bob, data1, read p, Charlie, data2, read g, Alice, admin |
Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 |
FROM golang:1.20 WORKDIR / COPY main.go / RUN go mod init casbin RUN go get github.com/casbin/casbin/v2 RUN go build main.go FROM ubuntu:latest WORKDIR / COPY --from=0 /main ./ COPY policy.csv / COPY model.conf / CMD ["./main"] |
ビルド・実行
$ docker build -t casbin .
$ docker run casbin
[Alice data1 read]: true
[Bob data1 write]: false
[Charlie data2 read]: true
特徴的なのは、ポリシー定義とモデル定義が外部ファイルで外出しにしている点です。このサンプルはシンプルですがやれることが集約されています。説明がなくとも上記コードと出力から何ができるのかよく理解できます。実際はサービスに組み込んだり、定義はDBに置くことが予想されます。
今回のテストはマルチステージビルドもポイントなのですが、Go言語は実行ファイルに簡単にできるので、ビルドはGoのビルド環境があるイメージの中で、実行はGo言語を含まない軽量のイメージで、ということが可能です。Javaでも同様のことをやりますが、Goの場合VMすらいらないので、この恩恵をより感じます。
$ docker images
REPOSITORY TAG
IMAGE ID CREATED SIZE
casbin latest
5778c8360b39 38 minutes ago 76.7MB
…
Goはまだ文法がよくかわることがありますので、バージョンきりかえが簡単にできることは、作業の効率化には欠かせません。