【CSPM】Prisma Cloud の API を呼び出してみた② ~長期間未使用のアクセスキーをPythonで一覧化してみた~

はじめに

今回は「Prisma Cloud の API を呼び出してみた」の第二弾です。
1回目はこちらで、APIでアラート件数を取得する方法を記載しています。

Prisma Cloudのアクセスキーについて解説後、最後に使用した日付が1か月前以上のアクセスキー一覧を取得するツールをPythonを使用して作成します。
アクセスキーの解説後、実際に作成したアクセスキーを使用して、最後に使用した日付が1ヵ月以上前のアクセスキー一覧を出力するツールをPythonで作成します。
このツールを使用することで1か月以上前のアクセスキー一覧がすぐに確認できるので、Prisma Cloudコンソールに行く手間などを省くことができます。

アクセスキーとは

Prisma Cloud APIにアクセスするための認証情報で、サードパーティとの結合にも使用できます。
アクセスキーIDとシークレットキーのペアで構成され、有効期限を設定可能です。
特定のロールに関連付けすることもできます。
また、アクセスキーに関連付けられたロールが削除されるとアクセスキーも削除されます。

アクセスキーの確認方法

  1. Prisma Cloud コンソールにアクセスします。
  2. 右上「Settings」>左ペイン「Access Control」>「Access Keys」に遷移します。
  3. 遷移後、各アクセスキーの権限情報が確認できます。

アクセスキー作成方法

  1. Prisma Cloud コンソールにアクセスします。
  2. 「Settings」>「Access Control」>「Access Keys」に遷移します。
  3. 以下画像に遷移します(アクセスキーの確認方法と同様)
  4. 右上の「Add」>「Access Key」から作成することができます。
    ※アクセスキーはログインに使用したロールに基づいて「Role」と「Permission Group」が紐づけられ作成されます。
       参考: アクセスキーの作成と管理
    今回は有効期限ありで作成します。            

    ラベル 入力フィールド
    Name 任意の名前
    Enable Expiration ONにすると有効期限を設定することができます

    以下画像は有効期限なし

    以下画像は有効期限あり
    Access Key Expirationが有効期限になります。任意の日付を指定してください

  5. 「Save」を押下後、アクセスキーを作成することができます。
    SecretAccessKeyは以下画像の画面でしかダウンロード、値のコピーを行うことができないので、今ダウンロードなどを行います。
    ダウンロード後、「Done」を押下します。
  6. 「アクセスキー作成方法」と同じ手順で画面を遷移し、作成した名前と同じアクセスキーがあることを確認します

Prisma Cloud APIを使用してアクセスキー一覧を取得するツールの作成

次は先ほど発行したアクセスキーとPrisma Cloud APIを使用して、アクセスキー一覧を取得できるツールを作成していきます。
1ヵ月使用していないアクセスキーの名前と最後にアクセスキーを使用したUnix時間を出力できるようにします。

ライブラリのインポート

今回使用するライブラリ群をインポートします。

import requests
import json
import time
from time import sleep
from datetime import datetime, timezone, timedelta

Prisma Cloud APIに必要なトークンの発行

Prisma CloudのAPIに必要なトークンを発行する関数を作成します。
ここで発行したアクセスキーとシークレットキーを使用します。
変数名usernameがアクセスキーで、変数名passwordがシークレットキーになっています。

def get_token():

    # 発行したアクセスキーを書く
    username = "12345"
    password = "12345"
    # https://pan.dev/prisma-cloud/api/cspm/app-login/
    url = "https://api.anz.prismacloud.io/login"

    # リクエストパラメータ(username,password)の編集
    payload = '{\"username\":\"' + username + \
        '\",\"password\":\"' + password + '\"}'
    headers = {
        "Accept": "application/json; charset=UTF-8",
        "Content-Type": "application/json; charset=UTF-8"
    }

    wasResponseError = False
    # APIリクエスト実行
    while True:
        # https://prisma.pan.dev/api/cloud/cspm/login#operation/app-login
        response = requests.request("POST", url, data=payload, headers=headers)

        # リクエスト実行結果の判定
        if response.status_code == 200:
            token = json.loads(response.text)['token']
            wasResponseError = False
            break
        else:
            print(f"You couldn't be authenticated [status_code:{response.status_code}]")
            # APIのベストプラクティス
            if wasResponseError:
                exit()
            else:
                sleep(32)
                wasResponseError = True
        
    return token

Prisma Cloud APIを使用してアクセスキー一覧を取得

発行したトークンを使用してアクセスキー一覧を取得する関数を作成します。
こちらの関数はPrisma Cloud の発行されているアクセスキー一覧を取得する関数になります。

def get_accesskeys(token):

    url = "https://api.anz.prismacloud.io/access_keys"
    payload = {}
    headers = {
        "Content-Type": "application/json; charset=UTF-8",
        "x-redlock-auth": token
    }

    wasResponseError = False
  # APIリクエスト実行
    while True:
        response = requests.request("GET", url, headers=headers, data=payload)

        if response.status_code == 200:
            access_key_data = json.loads(response.text)
            wasResponseError = False
            break
        else:
            print(f"Bad Request[status_code:{response.status_code}]")
            if wasResponseError:
                exit()
            else:
                sleep(32)
                wasResponseError = True

    return access_key_data

1ヵ月前のUnix時間を算出する処理の作成

1か月前のUnix時間を算出する必要があるので1ヵ月以上前のUnix時間を算出する関数を作成します。

def get_one_month_ago_unix_time():
    # 現在の日付を取得 
    current_time = datetime.now()
        
    # 1か月前の日時を取得
    one_month_ago = current_time - timedelta(days=30)

    # 1か月前のDatetimeオブジェクトをUnix時間に変換
    one_month_ago_unix_time = int(time.mktime(one_month_ago.timetuple())) * 1000

    return one_month_ago_unix_time

Unix時間を日本時間に変換する処理の作成

Unix時間を日本時間に変換する関数を作成します。

def convert_unix_millis_to_jst(unix_millis):
    # ミリ秒を秒に変換
    unix_seconds = unix_millis / 1000.0
    
    # Unix時間をUTCのdatetimeオブジェクトに変換
    utc_time = datetime.fromtimestamp(unix_seconds, tz=timezone.utc)
    
    # 日本標準時(JST、UTC+9)に変換
    jst_time = utc_time.astimezone(timezone(timedelta(hours=9)))
    
    return jst_time

アクセスキー一覧を出力する処理の作成

アクセスキー一覧を出力する関数を作成します。

def print_list_accesskeys(access_key_data, one_month_ago_unix_time, jst_time):
    
    print("=== 長期間使用されていないアクセスキー一覧 ===")
    for data in access_key_data:
        # 最後に使用した時間が1ヵ月以上前だった場合
        if data['lastUsedTime'] < one_month_ago_unix_time:
            print(f"AccessKey Name: {data['name']}, Last Used: {jst_time.strftime('%Y-%m-%d')}")

main関数の作成とエントリーポイントの作成

最後に1~6までに作成した関数を使用したmain関数とエントリーポイントを作成します。

def main():
    # トークンを取得
    token = get_token()

    # アクセスキー一覧を取得する(JSON形式)
    access_key_data = get_accesskeys(token)
    
    #1ヵ月前のUnixTime時間を取得
    one_month_ago_unix_time = get_one_month_ago_unix_time()

    # UnixTime時間から日本時間に変換
    jst_time = convert_unix_millis_to_jst(one_month_ago_unix_time)

    # アクセスキー一覧を出力する
    print_list_accesskeys(access_key_data, one_month_ago_unix_time, jst_time)

if __name__ == "__main__": 
  main()

プログラム実行結果

プログラムを実行すると以下の様に出力されます。
※name-accesskeysは実際にはPrisma Cloudコンソールのアクセスキー欄と同じ名前が出力されています。
=== 長期間使用されていないアクセスキー一覧 ===
AccessKey Name: name-accesskeys, Last Used: 2025-03-24
AccessKey Name: name-accesskeys, Last Used: 2025-03-24
AccessKey Name: name-accesskeys, Last Used: 2025-03-24
AccessKey Name: name-accesskeys, Last Used: 2025-03-24
AccessKey Name: name-accesskeys, Last Used: 2025-03-24
AccessKey Name: name-accesskeys, Last Used: 2025-03-24

プログラムの全体像

import requests
import json
import time
from time import sleep
from datetime import datetime, timezone, timedelta

# PrismaCloudのAPIに必要なトークンを発行する
def get_token():

    # 発行したアクセスキーを書く(ハードコードは良くないためconfigファイル等に格納するのがベスト)
    username = "891a8cef-82df-434d-8b2a-e2f4145aa4b4"
    password = "ZJMp9W8xabxNZrwcC330kG3rTPg="

    url = "https://api.anz.prismacloud.io/login"

    # リクエストパラメータ(username,password)の編集
    payload = '{\"username\":\"' + username + \
        '\",\"password\":\"' + password + '\"}'
    headers = {
        "Accept": "application/json; charset=UTF-8",
        "Content-Type": "application/json; charset=UTF-8"
    }

    wasResponseError = False
    # リクエスト実行(POST / login APIを使用してJWTをを取得)
    while True:
        # https://prisma.pan.dev/api/cloud/cspm/login#operation/app-login
        response = requests.request("POST", url, data=payload, headers=headers)

        # リクエスト実行結果の判定
        if response.status_code == 200:
            token = json.loads(response.text)['token']
            wasResponseError = False
            break
        else:
            print(f"You couldn't be authenticated [status_code:{response.status_code}]")
            # APIのベストプラクティス
            if wasResponseError:
                exit()
            else:
                sleep(32)
                wasResponseError = True
        
    return token

# アクセスキー一覧を返すAPIを叩く
def get_accesskeys(token):
    
    url = "https://api.anz.prismacloud.io/access_keys"
    payload = {}
    headers = {
        "Content-Type": "application/json; charset=UTF-8",
        "x-redlock-auth": token
    }

    wasResponseError = False
    while True:
        response = requests.request("GET", url, headers=headers, data=payload)

        if response.status_code == 200:
            access_key_data = json.loads(response.text)
            wasResponseError = False
            break
        else:
            print(f"Bad Request[status_code:{response.status_code}]")
            if wasResponseError:
                exit()
            else:
                sleep(32)
                wasResponseError = True

    return access_key_data

# 一カ月前のUnix時間を返す
def get_one_month_ago_unix_time():
    # 現在の日付を取得 
    current_time = datetime.now()
        
    # 1か月前の日時を取得
    one_month_ago = current_time - timedelta(days=30)

    # 1か月前のDatetimeオブジェクトをUnix時間に変換
    one_month_ago_unix_time = int(time.mktime(one_month_ago.timetuple())) * 1000

    return one_month_ago_unix_time

# unixミリ秒を日本時間に変換
def convert_unix_millis_to_jst(unix_millis):
    # ミリ秒を秒に変換
    unix_seconds = unix_millis / 1000.0
    
    # Unix時間をUTCのdatetimeオブジェクトに変換
    utc_time = datetime.fromtimestamp(unix_seconds, tz=timezone.utc)
    
    # 日本標準時(JST、UTC+9)に変換
    jst_time = utc_time.astimezone(timezone(timedelta(hours=9)))
    
    return jst_time

def print_list_accesskeys(access_key_data, one_month_ago_unix_time, jst_time):
    
    print("=== 長期間使用されていないアクセスキー一覧 ===")
    for data in access_key_data:
        # 最後に使用した時間が1ヵ月以上前だった場合
        if data['lastUsedTime'] < one_month_ago_unix_time:
            print(f"AccessKey Name: {data['name']}, Last Used: {jst_time.strftime('%Y-%m-%d')}")
    
def main():
    # トークンを取得
    token = get_token()

    # アクセスキー一覧を取得する(JSON形式)
    access_key_data = get_accesskeys(token)
    
    #1ヵ月前のUnixTime時間を取得
    one_month_ago_unix_time = get_one_month_ago_unix_time()

    # UnixTime時間から日本時間に変換
    jst_time = convert_unix_millis_to_jst(one_month_ago_unix_time)

    # アクセスキー一覧を出力する
    print_list_accesskeys(access_key_data, one_month_ago_unix_time, jst_time)

if __name__ == "__main__":
    main()

さいごに

今回はアクセスキーの解説とアクセスキー一覧を出すAPIで簡単なツールを作成してみました。

当社では、複数クラウド環境の設定状況を自動でチェックし、設定ミスやコンプライアンス違反、異常行動などのリスクを診断するCSPMソリューションを販売しております。

マルチクラウド設定診断サービス with CSPM| SCSK株式会社

ご興味のある方は是非、お気軽にお問い合わせください。

タイトルとURLをコピーしました