SUPER-G.EEK.JP

twitter: @hum_op_dev
github: ophum

Hashicorp Vaultの認証にOpenID Connect(oidc)を使ってみる

目次

vault の認証に OpenID Connect(oidc)を設定してみました。

検証環境

以下の docker-compose.yml を使用しました。(永続化はしていません。)

 1version: "3"
 2
 3services:
 4  vault:
 5    image: vault
 6    environment:
 7      VAULT_LOCAL_CONFIG: |-
 8        {"backend": {"file": {"path": "/vault/file"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h", "ui": true, "disable_mlock": true}        
 9    ports:
10      - 8200:8200
11  keycloak:
12    image: jboss/keycloak
13    ports:
14      - 8080:8080
15    environment:
16      KEYCLOAK_USER: admin
17      KEYCLOAK_PASSWORD: admin

実行

1$ docker compose up -d

また、hosts(Windows はC:\Windows\System32\drivers\etc\hosts) に以下を追記します。(vault から keycloak へのアクセスは docker 内部での名前解決される keycloak を使用するためログイン時に指定される keycloak への URL のアドレスが keycloak になります。そのため、ホストマシンでも keycloak の名前解決がされる必要があります。)

1127.0.0.1 keycloak

Keycloak の設定

http://keycloak:8080/auth/admin/ にアクセスしユーザー名(admin)、パスワード(admin)でログインします。

client の追加

左メニューから Clients を選択し、テーブル右上のCreateボタンを押下します。

Client IDvault-oidcClient Protocolopenid-connectを入力しSaveボタンを押下します。

作成されると client の設定ページに遷移します。
以下の項目を変更します。

Access Typepublicからconfidentialに変更し、
Valid Redirect URIsに以下の URL を追加します。

admin ユーザーのメールアドレスを設定

oidc での認証後に vault で email の情報を利用したいため admin ユーザーに email を追加します。

左メニューから Users を選択肢、テーブル上部にあるView all usersボタンを押下しUsernameadminのリンクを押下し設定画面に遷移します。

Email にadmin@example.comを入力しSaveボタンを押下します。

user の追加

ログイン用のユーザーを追加しておきます。

左メニューから Users を選択し、テーブル右上のAdd userボタンを押下します。

Usernameuser, Emailuser@example.comを入力しSaveボタンを押下します。

作成されるとユーザーの設定ページに遷移します。
Credentials タブをクリックしパスワードをセットします。

vault の設定

http://localhost:8200/ui にアクセスしログインします。

ログイン時に使用するトークンは、以下のようにして確認できます。(dev サーバーのためログに出力されている)

1$ docker compose logs vault | grep "Root Token"
2vault-keycloak-vault-1  | Root Token: hvs.2iU2XXolR61jjKITfSJTZaJ3

UI のヘッダーメニューからAccessを押下すると有効な認証方法の一覧が見れます。
初期状態では token による認証のみ有効になってます。

OIDC を有効にするためテーブル右上のEnable new methodを押下します。

OIDC を選択しNextボタンを押下します。

Path はoidcのままEnable Methodボタンを押下します。

有効化すると OIDC の設定画面に遷移するので以下の項目を編集します。

OIDC discovery URLhttp://keycloak:8080/auth/realms/master/を入力。

OIDC OptionsOIDC client IDvault-oidcを入力。

OIDC OptionsOIDC client secretに keycloak のvault-oidcclient のCredentialsタブで見れるSecretを入力。

ロールの作成

OIDC で認証する際のロールを作成します。この操作は CLI から行います。

以下のようにして Root Token を利用して CLI から操作できるようにします。

 1$ docker compose exec vault sh
 2/ # export VAULT_TOKEN=hvs.2iU2XXolR61jjKITfSJTZaJ3
 3/ # export VAULT_ADDR=http://localhost:8200
 4/ # vault status
 5Key             Value
 6--- -----
 7Seal Type       shamir
 8Initialized     true
 9Sealed          false
10Total Shares    1
11Threshold       1
12Version         1.11.1
13Build Date      2022-07-19T20:16:47Z
14Storage Type    file
15Cluster Name    vault-cluster-7b242bf7
16Cluster ID      16cb4252-6c90-8a5a-49f9-57fafa8a2bd5
17HA Enabled      false

以下のコマンドを実行しロールを作成します。

user_claim には userinfo で提供されている項目のうちユニークなものを選びます。
公式ドキュメントなどではsubを利用するようになっており Keycloak の場合は ID(uuid)が入ります。

今回はemailを利用するようにします。

 1$ vault write auth/oidc/role/keycloak -<<EOF
 2{
 3  "user_claim": "email",
 4  "allowed_redirect_uris": [
 5    "http://localhost:8200/ui/vault/auth/oidc/oidc/callback",
 6    "http://localhost:8250/oidc/callback"
 7  ],
 8  "role_type": "oidc",
 9  "policies": "",
10  "ttl": "1h"
11}
12EOF

以下のように設定されているのが確認できます。

 1/ # vault read auth/oidc/role/keycloak
 2Key                        Value
 3--- -----
 4allowed_redirect_uris      [http://localhost:8200/ui/vault/auth/oidc/oidc/callback http://localhost:8250/oidc/callback]
 5bound_audiences            <nil>
 6bound_claims               <nil>
 7bound_claims_type          string
 8bound_subject              n/a
 9claim_mappings             <nil>
10clock_skew_leeway          0
11expiration_leeway          0
12groups_claim               n/a
13max_age                    0
14not_before_leeway          0
15oidc_scopes                <nil>
16role_type                  oidc
17token_bound_cidrs          []
18token_explicit_max_ttl     0s
19token_max_ttl              0s
20token_no_default_policy    false
21token_num_uses             0
22token_period               0s
23token_policies             []
24token_ttl                  1h
25token_type                 default
26ttl                        1h
27user_claim                 email
28user_claim_json_pointer    false
29verbose_oidc_logging       false

OIDC でログインしてみる

準備が完了したので、実際にログインしてみます。

以下のように認証方法を OIDC に、Role に先ほど作成したroleを入力してSign in with OIDC Providerボタンを押下します。

ログインウィンドウが開くので、作成したユーザーのユーザー名とパスワードを入力します。

ログインに成功すると secret engine の一覧などが見れるようになります。

ロールのポリシーについて

ロールを作成する際ポリシーを空で作成しました。そのため、Root Token でログインしたときに見えていた kv のsecret/が OIDC でログインしたユーザーでは見えません。

以下のように ポリシーを作成・指定すると見えるようになります。

 1$ vault policy write oidc-user - << EOF
 2path "secret/secret/*" {
 3  capabilities = ["create", "update", "delete", "read", "list", "sudo"]
 4}
 5EOF
 6$ vault write auth/oidc/role/keycloak -<<EOF
 7{
 8  "user_claim": "email",
 9  "allowed_redirect_uris": [
10    "http://localhost:8200/ui/vault/auth/oidc/oidc/callback",
11    "http://localhost:8250/oidc/callback"
12  ],
13  "role_type": "oidc",
14  "policies": ["default", "oidc-user"],
15  "ttl": "1h"
16}
17EOF

さいごに

OIDC を利用することでユーザーの管理は Keycloak のようなソフトウェアで一元管理しつつ vault にログインできました。

今回の検証では、ポリシーを適用することで OIDC ログインしたユーザーの操作を制限しました。しかし、これでは OIDC ログインしたすべてのユーザーが同じ権限で操作できてしまいます。
その場合、例えばチーム毎に機密にしておきたい情報を操作されてしまいます。ポリシーを細かく適用するために、グループ・エンティティ・エイリアスといった仕組みを使用できます。余力があれば記事にしようと思います。

参考文献