ノート:

OCI FunctionsおよびOCI Queueを使用した承認者に管理権限を公開せずにユーザー機能を認可

イントロダクション

ユーザー機能の更新は、特にユーザーに認可された権限がコンソール機能やAPIキーのように機密である場合、多くの企業にとって重要なニーズです。ただし、Oracle Cloud Infrastructure (OCI)ドキュメントにあるかぎり、明示的に許可するOracle Cloud Infrastructure Identity and Access Management (OCI IAM)ポリシーがある場合でも、管理者グループのユーザーのみがユーザー機能を認可できます。詳細は、ユーザーの管理を参照してください。

このチュートリアルでは、ユーザーがOCI IAMドメインの管理者グループに属していないが、OCI Connector Hubの新しくリリースされた機能を利用してOCI QueueとOCI Functionsを統合することで、ユーザー機能を認可する機能を持っている必要があるシナリオのソリューションを示します。

ソリューション・アーキテクチャ

図SolutionArchitecture.pngの説明

目的

タスク1: OCIキューからOCI関数へのメッセージング・チャネルの作成

ソリューションの重要な部分は、ユーザーの機能を変更するために必要な権限を承認者がリクエストを承認するために必要な権限から分離することです。

  1. 受信リクエストのOCIキューを作成します。詳細については、Creating a Queueを参照してください。

  2. ユーザーの認可に使用するOCI関数を作成します。詳細は、ファンクションの作成を参照してください。

  3. OCI Connector Hubを介してOCI QueueとOCI Functionsの統合を構成します。ソースが作成されたOCIキューで指定され、ターゲットがOCI関数であることを確認してください。このチュートリアルでは、オプションのタスクは空のままにします。詳細は、OCI Connector HubでのソースとしてのOCIキューの可用性の発表を参照してください。

タスク2: OCI IAMポリシーと動的グループの構成

リクエストを取得するために承認者のロールをOCIキューに分割し、リクエストを実行するためにOCI関数を分割した後、権限が悪用されないように厳密なOCI IAMポリシーを構成する必要があります。実装にルート・コンパートメントの使用を要求する顧客をサポートするためにこのソリューションを構築したため、OCI IAM部分のルート・コンパートメントからすべての構成をデモします。

  1. キュー・メッセージをターゲットOCIキューにプッシュできるのは承認者のみです。

    Allow group 'testApprover' to use queues in tenancy
    

    このポリシーを追加することで、testApproverグループのユーザーは、キューを使用してコンソール・アクセス・リクエストを受信できます。次の例に示すように、queue-pushリソースタイプに対するアクセス権のみを指定することによって、グループに対してさらに制限を課すことができます。

    use queue-push in compartment <compartment> where target.queue.id = '<queue_ocid>'
    
  2. 次の一致ルールを指定して、OCI関数を含めるように動的グループを構成します。

    ALL{resource.type='fnfunc',resource.id='ocid.fnfunc.oc1.....'}
    

    この動的グループは、ドメイン内のユーザーを管理するためにOracle Identity Cloud Serviceロールで認可されます。

  3. 動的グループのOracle Identity Cloud Serviceロールを構成します。

    IDCSドメイン・ロール

    図DomainRole.pngの説明

  4. OCIキューによってのみ起動できるようにOCI関数を構成します。次の例では、呼出しのソースのみをキューに制限します。実際には、リソースでタグを使用することで、より厳密になる場合があります。詳細は、タグを使用したアクセスの管理を参照してください

    Allow service faas to use functions-family in tenancy where request.principal.type='queues'
    

タスク3: OCIファンクション・コードの構成

OCI FunctionsがOCI Queueから取得したリクエストを実際に実行するには、Pythonコードを作成する必要があります。

  1. OCI Queueメッセージは、dataオブジェクトの関数に渡されます。

    def handler(ctx, data: bytes = None) -> response.Response:
        try:
        # Parse the message from the OCI Queue
            if data:
            message = json.loads(data.getvalue().decode('utf-8'))
            else:
            message = "no useremail received"
    
  2. リソース・プリンシパルを使用して認証します。

    ノート:次のコード行がIDEで機能していない可能性があります。

    identity = IdentityClient({}, signer=oci.auth.signers.get_resource_principals_signer(), region=region)
    
  3. 渡されたユーザーの電子メールを、ユーザーのOracle Cloud Identifier (OCID)に変換します。

    def get_user_ocid_by_email(identity_client,email,tenancy_id):
        # List all users in the tenancy
        users = oci.pagination.list_call_get_all_results(identity_client.list_users,tenancy_id).data
    
        # Find the user with the matching email address
        for user in users:
            if user.email.lower() == email.lower():
                return user.id
    
        return None
    
  4. IdentityClient関数を使用して、ユーザー機能をリソース主体で更新します。

    # Get the user by email address
    user_ocid = get_user_ocid_by_email(identity,user_email,tenancy)
    
    # Update user capabilities (example: enable API keys)
    update_details = oci.identity.models.UpdateUserCapabilitiesDetails(
        can_use_api_keys=True,
        can_use_auth_tokens=True,
        can_use_console_password=True,
        can_use_customer_secret_keys=True,
        can_use_db_credentials=True,
        can_use_o_auth2_client_credentials=True,
        can_use_smtp_credentials=True
    )
    
    # Update the user
    identity.update_user_capabilities(user_ocid, update_details)
    
  5. 作成したOCI関数にファンクション・コードをデプロイします。OCI関数のデプロイの詳細なステップは、OCI関数の構成ノートを参照してください

タスク4: 変更のテスト

ターゲット・キューにメッセージを送信して、変更をテストします。OCIコンソールを使用するか、OCI Cloud Shellを含む任意のSDKを使用できます。

Send Message

図send-message.pngの説明

調査

図examine.pngの説明

トラブル・シューティング

OCIRを使用するためのOCIファンクションの構成

OCIRをOCI関数のリポジトリとして使用している場合、いくつかの問題があなたをブロックしている可能性があり、解決策を見つけるのは容易ではありません。現時点では、このような問題を回避するための明確なガイドは特に証明されていません。

  1. OCIRリポジトリとOCI関数の両方の特定のコンパートメントをファンクション・コンテキストとして構成します。デフォルトでは、コンソールの指示ページに従ってクラウド・シェル・コマンドを実行した場合でも、OCIRリポジトリのコンテキストはルート・コンパートメントを指しています。

    fn update context oracle.compartment-id ocid1.tenancy.oc1.....
    

    ノート:この部分は、oracle.compartment-idと同様に非常に誤解を招くものです。このプロパティは関数とOCIRの両方に対するものだと考えられますが、OCIRにはimage-compartment-idという個別のプロパティがあります。そのため、名前付きコンパートメントを使用してファンクションを実行し、イメージを格納する場合は、次のOCI Cloud Shellコマンドを使用して、両方のコンパートメントIDが明示的に設定されていることを確認します。また、OCIRとファンクション間のアクションが別の名前付きコンパートメントからのものである場合も、それらのアクションを許可するように適切なOCI IAMポリシーを構成する必要があります。

    fn update context oracle.image-compartment-id <compartment-ocid>
    fn update context oracle.compartment-id <compartment-ocid>
    

    これが正しく行われない場合、有線403エラーが発生し、image-compartment-idに気付いていない可能性があるため、手がかりを見つけるのは困難です。

  2. イメージを処理するためにdocker APIを適用する必要があるため、OCI Cloud Shellがdocker.ioからアクセス可能なネットワーク環境から起動されている間、OCIRを使用するためのファンクションの構成。通常、OCIサービス・ネットワークではアクセスできません。OCI Cloud Shellを使用している場合は、コンテナ・デプロイメントにパブリック・ネットワークを使用することをお薦めします。

    詳細は、Functions: クラウド・シェルのスタート・ガイドを参照してください。

  3. ここで考えられるもう1つのブロッカは、キュー・メッセージをファンクション入力に渡す場合です。変数を渡す方法については、他の記事で複数の参照を見つけることができますが、実際にはjsonを入力し、Pythonコードのdataオブジェクトで受信するのと同じくらい簡単です。

    ノート: Javascriptタイプのjsonを一重引用符または引用符なしで使用することは避けてください。ここでは、厳密な構文のみがOCIキューで認識されるようになりました。

    {"name":"John"}
    

承認

その他の学習リソース

docs.oracle.com/learnの他のラボを確認するか、Oracle Learning YouTubeチャネルで無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスしてOracle Learning Explorerになります。

製品ドキュメントは、Oracle Help Centerを参照してください。