Okta WorkflowsのLambdaコネクタを試してみた

Okta WorkflowsのLambdaコネクタを試してみた

2026.04.23

データ事業本部のueharaです。

今回は、Okta WorkflowsのLambdaコネクタを試してみたいと思います。

はじめに

Okta Workflowsは、ID管理や外部アプリ連携などの業務プロセスを、ノーコードで自動化できるプラットフォームです。

その中の機能の1つとして、AWS Lambdaを実行することができる Lambda コネクタ があります。

https://help.okta.com/wf/ja-jp/content/topics/workflows/connector-reference/awslambda/awslambda.htm

今回はこのLambdaコネクタを利用して、 Okta上でユーザをディアクティベート(非アクティブ化)した際に、無効化されたユーザの情報をLambdaに連携する というのを試してみたいと思います。

ユースケースとしては、退職等に伴いOkta上でユーザを非アクティブ化した際、Lambdaにユーザ情報を渡し特定サービスと連携しながら退職に伴う処理を行うということが考えられます。

全体の流れとしては、以下のような形になります。

Oktaでイベント発生(ユーザのディアクティベート)

Okta Workflows(User Deactivated トリガー)
    ↓  AWS Lambda コネクタ
AWS Lambda(ユーザ情報の受け取り)

CloudWatch Logs(ログ確認)

今回はサンプルなので、Lambdaでは受け取ったユーザ情報をログに出力するのみとします。

API GatewayやLambda Function URLsも不要で、Lambdaを直接呼び出してもらう形となります。

やってみた

(AWS)SAMアプリケーションの作成

AWSリソースの作成には AWS SAM (Serverless Application Model) を使用します。

今回作成するリソースは以下の通りです。

リソース 名前 用途
Lambda 関数 okta-retirement-receiver ユーザ情報を受け取りログ出力を行う
Lambda 実行ロール okta-retirement-receiver-role CloudWatchへのログ出力権限を持つ
IAM ポリシー okta-workflows-invoke-retirement-receiver Lambdaの実行権限を持つ
IAM ユーザー okta-workflows-lambda-invoker Okta Workflowsの接続用ユーザ
(アクセスキーは後に手動で発行)

SAMアプリケーションのディレクトリ構成は以下の通りです。

sam-app
├── samconfig.toml
├── src
│   └── lambda_function.py
└── template.yaml

まず、 samconfig.toml は以下のように記載しました。

samconfig.toml
version = 0.1

[default]
region = "ap-northeast-1"

[default.build.parameters]
debug = true

[default.deploy.parameters]
stack_name = "okta-workflows-test"
s3_bucket = "cm-da-uehara"
s3_prefix = "sam-deploy"
capabilities = "CAPABILITY_NAMED_IAM"
confirm_changeset = true

バケット名やスタック名などは任意なので、お手元で確認する際は適宜変更ください。

SAMのテンプレートである template.yaml は以下の通りです。

template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: "SAM application for verifying the Okta Workflows AWS Lambda connector."

# ============================================================
# Globals
# ============================================================
Globals:
  Function:
    Runtime: python3.12
    Architectures:
      - x86_64
    Timeout: 30
    MemorySize: 128

# ============================================================
# Resources
# ============================================================
Resources:

  # ----------------------------------------------------------
  # Lambda function: retired user information receiver
  # ----------------------------------------------------------
  OktaRetirementReceiverFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: okta-retirement-receiver
      Description: >-
        Verification Lambda function that receives retired user information
        from the Okta Workflows Lambda connector and logs it to CloudWatch Logs.
      CodeUri: src/
      Handler: lambda_function.lambda_handler
      Role: !GetAtt LambdaExecutionRole.Arn

  # ----------------------------------------------------------
  # Lambda execution role
  # ----------------------------------------------------------
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: okta-retirement-receiver-role
      Description: >-
        Execution role for the okta-retirement-receiver Lambda function.
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  # ----------------------------------------------------------
  # IAM policy for Okta Workflows connectivity
  # ----------------------------------------------------------
  OktaWorkflowsInvokePolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: okta-workflows-invoke-retirement-receiver
      Description: >-
        Least-privilege policy for the Okta Workflows AWS Lambda connector.
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: ListLambdaFunctions
            Effect: Allow
            Action: lambda:ListFunctions
            Resource: '*'
          - Sid: InvokeOktaRetirementReceiverFunction
            Effect: Allow
            Action: lambda:InvokeFunction
            Resource: !GetAtt OktaRetirementReceiverFunction.Arn

  # ----------------------------------------------------------
  # IAM user for Okta Workflows connectivity
  # (programmatic access only; access key must be issued manually after deployment)
  # ----------------------------------------------------------
  OktaWorkflowsLambdaInvokerUser:
    Type: AWS::IAM::User
    Properties:
      UserName: okta-workflows-lambda-invoker
      ManagedPolicyArns:
        - !Ref OktaWorkflowsInvokePolicy

# ============================================================
# Outputs
# ============================================================
Outputs:
  LambdaFunctionName:
    Description: Lambda function name
    Value: !Ref OktaRetirementReceiverFunction

  LambdaFunctionArn:
    Description: Lambda function ARN
    Value: !GetAtt OktaRetirementReceiverFunction.Arn

  IamUserName:
    Description: IAM user name for Okta Workflows connectivity
    Value: !Ref OktaWorkflowsLambdaInvokerUser

  IamPolicyArn:
    Description: IAM policy ARN for Okta Workflows connectivity
    Value: !Ref OktaWorkflowsInvokePolicy

作成されるリソースについては、先に記載したリソースの表の通りとなります。

Lambda関数のスクリプト src/lambda_function.py については以下の通りです。

src/lambda_function.py
from __future__ import annotations

import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def _extract_body(event: dict) -> dict:
    """受信イベントからリクエストボディを抽出する

    Lambda コネクター経由では event 自体が Payload となるが、
    API Gateway / Function URL 経由では event.body に JSON 文字列が包まれる形になる。
    どちらの呼び出し形式でも動作するよう両対応。

    Args:
        event (dict): Lambda が受け取るイベントオブジェクト

    Returns:
        dict: リクエストボディを表す辞書
    """
    if isinstance(event, dict) and isinstance(event.get("body"), str):
        try:
            return json.loads(event["body"])
        except json.JSONDecodeError:
            return {}
    return event if isinstance(event, dict) else {}

def _response(status_code: int, payload: dict) -> dict:
    """Lambda レスポンス辞書を生成する

    Args:
        status_code (int): HTTP ステータスコード
        payload (dict): レスポンスに含めるデータ

    Returns:
        dict: statusCode とペイロードをマージしたレスポンス辞書
    """
    return {"statusCode": status_code, **payload}

def lambda_handler(event: dict, context) -> dict:
    logger.info("受信 event: %s", json.dumps(event, ensure_ascii=False, default=str))

    body = _extract_body(event)

    email = (body.get("email") or "").strip()
    user_id = (body.get("user_id") or "").strip()
    display_name = (body.get("display_name") or "").strip()
    action = (body.get("action") or "").strip()

    logger.info(
        "退職者情報を受信しました / action=%s, email=%s, user_id=%s, display_name=%s",
        action,
        email,
        user_id,
        display_name,
    )

    result = {
        "message": "退職者情報を正常に受信しました",
        "received": {
            "action": action,
            "email": email,
            "user_id": user_id,
            "display_name": display_name,
        },
    }

    logger.info("処理完了: %s", json.dumps(result, ensure_ascii=False))
    return _response(200, {"result": result})

ここでは、受け取ったペイロードをログに出力して、そのまま返すだけのシンプルな実装にしています。

(AWS)デプロイと確認

ファイルの用意ができたら、以下コマンドでデプロイを行います。

$ sam deploy

デプロイが完了したら、 samconfig.toml で名前を指定したスタックの確認を行います。

以下のようにリソースが作成されていれば完了です。

20260423_okta_01

(AWS)IAM ユーザーのアクセスキー発行

SAMで作成したIAM ユーザ( okta-workflows-lambda-invoker )のアクセスキーを手動で発行します。

『IAMコンソール』 → 『ユーザー』 → 『okta-workflows-lambda-invoker』 → 『アクセスキーを作成』 と進みます。

20260423_okta_02

ユースケースは『サードパーティーサービス』を選択します。

発行された アクセスキーシークレットアクセスキー を控えておきます。

20260423_okta_03

これでAWS側の準備は完了です。

(Okta)Workflowsのフロー作成

左側のタブから『Workflowsコンソール』へと遷移します。

20260423_okta_04

『New Flow』の『From scratch』からフローを作成します。

20260423_okta_05

トリガー設定

まず、トリガーの設定を行います。

左側のカードの『Add event』を選択します。

20260423_okta_06

『Okta』を選択します。

20260423_okta_07

『User Deactivated』を選択します。

20260423_okta_08

このトリガーはOktaでユーザが非アクティブ化されたときに発火します。

完了するとトリガーが追加されると思います。

追加されたトリガーの『New Connection』を選択します。

20260423_okta_09

Oktaの情報を入力します。

20260423_okta_11

Domainはご自身のOktaのURLの -admin を除いたものを入力して下さい。
例: xxx-yyy-admin.okta.com の場合 xxx-yyy.okta.com となります。

接続が成功すると、以下のようにOutputの欄が表示されます。

20260423_okta_12

Read Userアクションの追加

トリガーから取得できるユーザ情報は限られているため、次に Read User アクションを追加します。

先ほどと同じ要領で、追加したトリガーの右のカードの『Add app action』から『Okta』を選択し、『Read User』アクションを追加します。

20260423_okta_13

追加のプロパティとして、Profile Propertiesの『Primary email』と『Display name』を取得するようにします。

20260423_okta_14

『Save』で保存が完了したら、Inputの『ID or Login』にトリガーの『Okta User』の『ID』をドラッグ&ドロップで接続します。

この時点で、以下のようになっているかと思います。

20260423_okta_15

ペイロードの作成

次に、『Read User』で取得した情報をLambdaに渡すためのペイロードを作成します。

右のカードの『Add function』から、『Object』を選択します。

20260423_okta_16

Objectの中の『Construct』を選択します。

20260423_okta_17

追加したConstructに対し action, email, user_id, display_name のキーを作成し、以下の通り設定します。(マッピングするものについては項目をドラッグ&ドロップして下さい)

項目名 設定値 備考
action notify_retirement 固定値
email Primary email Read Userからマッピング
user_id ID Read Userからマッピング
display_name Display name Read Userからマッピング

設定したキー項目は、そのまま『output』として出力するようにします。

ここまで設定すると、以下のようになっているかと思います。

20260423_okta_18

Lambda関数の呼び出し設定

最後に、Lambda関数の呼び出し設定を行います。

作成したConstructの右のカードから、『Add app action』を選択し、Lambdaを検索します。

20260423_okta_19

『Invoke』を選択します。

20260423_okta_20

するとLambdaが追加されると思うので、『New Connection』を選択します。

20260423_okta_21

ここで、AWSリソースの作成時に発行したアクセスキーとシークレットアクセスキーを入力します。リージョンはTokyoにします。

20260423_okta_22

接続が成功すると関数名が入力できるようになるため、作成したLambda関数である『okta-retirement-receiver』を入力します。

20260423_okta_23

Parameters設定で『invocationType』を『RequestResponse』とし、『payload』に先ほど追加したConstructのoutputをドラッグ&ドロップします。

20260423_okta_24

これでLambda関数の設定も完了です。

全体のワークフローは次の通りになっているかと思います。

20260423_okta_28

フローの保存と有効化

最後に、任意でフロー名を入力した後に保存をして、『Flow is OFF』を選択します。

20260423_okta_25

フローの有効化を行います。

20260423_okta_26

これで準備は完了です。

動作確認

AWS・Okta共に準備ができたので、動作確認を行います。

適当なユーザを選択し、非アクティブ化を行います。

20260423_okta_27

Workflowsの履歴を見ると、以下のように無事フローが動いていることが確認できました。

20260423_okta_29

20260423_okta_30

Lambdaのログを確認してみると、こちらも無事情報を取得できていることが分かります。

20260423_okta_31

最後に

今回は、Okta WorkflowsのLambdaコネクタを試してみました。

参考になりましたら幸いです。

参考文献

この記事をシェアする

関連記事