Check! Azure SDK for Python で Azure Key Vault をつかうには!(認証まわり対策)

  • 1
    Like
  • 0
    Comment

こんばんは! @dz_ こと大平かづみです。

Prologue - はじめに

Azure SDK for Python を使って、Azure Key Vault の利用を試みたところ、RBAC (Role Based Access Control ) の認証で苦戦したので、腹いせにその状況と対処をしたためます。

RBAC認証とSDK用 auth ファイルについて

Azure の認証情報について検討していたところ、以下の形式で json ファイルで扱えることがわかりました。

たとえば、新しく RBAC の認証を発行し、その情報を上記の JSON 形式で出力するには、下記の Azure CLI 2.0 のコマンドを利用できます。

CLIでRBACによる認証情報を発行(SDK用JSON出力オプション)
$ az login
$ az ad sp create-for-rbac --sdk-auth > auth-sample.json
SDK用JSONのサンプル(上記ドキュメントから引用)
{
    "clientId": "ad735158-65ca-11e7-ba4d-ecb1d756380e",
    "clientSecret": "b70bb224-65ca-11e7-810c-ecb1d756380e",
    "subscriptionId": "bfc42d3a-65ca-11e7-95cf-ecb1d756380e",
    "tenantId": "c81da1d8-65ca-11e7-b1d1-ecb1d756380e",
    "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
    "resourceManagerEndpointUrl": "https://management.azure.com/",
    "activeDirectoryGraphResourceId": "https://graph.windows.net/",
    "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
    "galleryEndpointUrl": "https://gallery.azure.com/",
    "managementEndpointUrl": "https://management.core.windows.net/"
}

SDK で認証情報を扱うには

また、環境変数 AZURE_AUTH_LOCATION に、このJOSNファイルのパスを設定しておけば、SDKが自動で読み込んでくれるとのこと。

そして、上記のリンク先にあるように、ほとんどの場合は azure.common.client_factory.get_client_from_auth_file を利用して、簡単にクライアントを生成してくれます。

Azure SDK for Python で Azure Key Vault を利用するには

KeyVaultClient では、 get_client_from_auth_file が使えないよう…

しかぁし!

Azure Key Vault のクライアント KeyVaultClient も、上記の方法で簡単に生成できると思い、やってみたところ… できない(´・ω・`)

azure-keyvaultのバージョン
$ pip show azure-keyvault
Name: azure-keyvault
Version: 0.3.5
...
KeyVaultClientではだめだった例
from azure.common.client_factory import get_client_from_auth_file
from azure.keyvault import KeyVaultClient
client = get_client_from_auth_file(KeyVaultClient)
KeyVaultClientではだめだったときのエラー
Traceback (most recent call last):
  File "sample.py", line 26, in <module>
    client = get_client_from_auth_file(KeyVaultClient)
  File "/usr/local/lib/python2.7/dist-packages/azure/common/client_factory.py", line 192, in get_client_fr
om_auth_file
    return get_client_from_json_dict(client_class, config_dict, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/azure/common/client_factory.py", line 132, in get_client_fr
om_json_dict
    return _instantiate_client(client_class, **parameters)
  File "/usr/local/lib/python2.7/dist-packages/azure/common/client_factory.py", line 31, in _instantiate_c
lient
    return client_class(**kwargs)
TypeError: __init__() got an unexpected keyword argument 'base_url'

KeyVaultClient の生成はこちらの方法で!

SDKのソースコードともにらめっこして、最終的にたどり着いたこちらの資料、この方法で行けましたー!いえーい!ヾ(o´∀`o)ノ

せっかくなので、上記を参考に AZURE_AUTH_LOCATION のパスを利用するサンプルコードを書いてみました。

sample.py
#!/usr/bin/env python

import json
import os

from azure.keyvault import KeyVaultClient, KeyVaultAuthentication
from azure.common.credentials import ServicePrincipalCredentials

def auth_callback(server, resource, scope):
    with open(os.environ.get('AZURE_AUTH_LOCATION')) as auth_file:
        auth = json.load(auth_file)

    credentials = ServicePrincipalCredentials(
        client_id=auth['clientId'],
        secret=auth['clientSecret'],
        tenant=auth['tenantId'],
        resource=resource
    )
    token = credentials.token
    return token['token_type'], token['access_token']

# クライアントを取得する
client = KeyVaultClient(KeyVaultAuthentication(auth_callback))

# シークレットを取得する
vault_base_url = 'https://<Key Vault の名前>.vault.azure.net/'
secret_name = '<シークレットの名前>'
secret_version = '' # バージョンを指定しない場合

secret = client.get_secret(vault_base_url, secret_name, secret_version)

シークレットの取得に関しては、下記のドキュメント参考にしました。

これですすめるー!いえーい!ヾ(o´∀`o)ノ

Epilogue - おわりに

ということで、だいぶん翻弄されましたが、SDKがオープンソースでソースコード読めば解けることとか、わかった時のうれしさとか、これだからエンジニアはやめられません (oゝω・o)ノ))