1. HOME
  2. Tech
  3. SlackからOkta APIを実行してみた
Tech

SlackからOkta APIを実行してみた

Tech

SlackからAPIを実行したいなと思っていて、実際に試してみたので、そのメモです。SlackからAPIを実行できるようにすると、以下のメリットが見込めます。

・オペレーションの簡略化(管理画面からポチポチ操作するのって意外と時間かかる)
・オペミスのリスク軽減(管理画面には色々なボタンがあるので、押し間違えるリスクがある)
・作業移管時に委譲する権限の最小化(管理者アカウントを渡すと、余計な権限が付随しがち)
・マニュアル作成の工数削減(管理画面のスクリーンショットをペタペタとマニュアルへ貼るより、コマンドベースのほうがテキストで済むので楽)

サンプルとして、SlackからOkta APIを実行する具体的な方法を紹介します。

完成形

流れ

(1) Slackアプリを作成して、Signing Secretを取得
(2) Google Cloud(GCP)でCloud Functionsを作成
(3) SlackアプリのSlash CommandにCloud Functionsを設定
(4) Slackアプリを追加

※注意
最小限のテストしかしていないため、これをこのまま業務に利用して、何かトラブルになったとしても責任は負いかねます。あくまでサンプルとしてご認識ください。

詳細な手順

Slackアプリを作成して、Signing Secretを取得

Slack API からSlackアプリを作成

Slack App作成

左メニュー[Basic Information]の中から、Signing Secretを取得。

Google Cloud(GCP)でCloud Functionsを作成

ファンクションの構成

Cloud Functionsは第2世代がリリースされているが、うまく動作しなかったので第1世代で。

認証は「未認証の呼び出しを許可」にチェック。SlackからAPIを実行するにあたって、Cloud IAMが利用できないので。ただし、どこからでも呼び出されてしまうので、必ずコード内でSlackのSigning Secretで認証をかけて、API実行部分は実行できないようにする。

そうすることで、Cloud Functions自体はどこからでも呼び出せるものの、本体であるAPI実行部分は許可したSlackアプリからしか呼び出せないようにできる。

Cloud Functions 構成

ソース

import requests
import hmac
import hashlib

# Okta Domain(***.okta.com の形式で入力)
OKTA_DOMAIN = "dev-***.okta.com"

# OktaのAPIキー
OKTA_API_KEY = "ここに入れる"

# Slack AppのSigning Secret
SLACK_SIGNING_SECRET = "ここに入れる"

def get_user_status(user_id):
    url = f"https://{OKTA_DOMAIN}/api/v1/users/{user_id}"

    headers = {
        "Accept": "application/json",
        "Content-Type": "application/json",
        "Authorization": f"SSWS {OKTA_API_KEY}"
    }

    response = requests.get(url, headers=headers)

    if response.status_code == 200:
        user_data = response.json()
        user_status = user_data.get("status")
        return user_status
    else:
        print(f"Error retrieving user {user_id}: {response.text}")
        return None

def okta_user_status(request):
    # Slackからのリクエスト検証
    request_body = request.get_data(as_text=True)
    timestamp = request.headers.get('X-Slack-Request-Timestamp')
    sig_basestring = f"v0:{timestamp}:{request_body}".encode("utf-8")
    my_signature = 'v0=' + hmac.new(SLACK_SIGNING_SECRET.encode("utf-8"), sig_basestring, hashlib.sha256).hexdigest()
    slack_signature = request.headers.get('X-Slack-Signature')
    if not hmac.compare_digest(my_signature, slack_signature):
        return {"statusCode": 401}

    user_id = request.form.get('text')

    user_status = get_user_status(user_id)

    if user_status is not None:
        response_text = f"User {user_id} status: {user_status}"
    else:
        response_text = f"Error retrieving user {user_id}"

    return response_text

SlackアプリのSlash CommandにCloud Functionsを設定

作成したSlackアプリの Features > Slash Commands から設定します。

Slash_Commands_Setting

Slackアプリを追加

あとはSlackから、作成したSlackアプリを追加すればOK。

こういうの、メモしておかないと忘れるので、自分のために残しました。
誰かに参考にもなったら嬉しいです。