Jamf Pro Classic APIのBasic認証をBearer認証に置き換える

  • Apple
  • Apple Blog
  • Jamf Pro Classic APIのBasic認証をBearer認証に置き換える
  • Jamf Pro Classic APIのBasic認証をBearer認証に置き換える

    Jamf ProのAPIとは?

    Jamf社が提供するAppleデバイスの管理に特化したMDM、Jamf Pro。
    標準機能だけでも柔軟な管理が可能ですが、Jamf ProではAPIが公開されており、これを活用することでさらに様々な要件を実装することが可能です。

    例えば、Macのコンピュータ名を会社の管理番号で自動付番したり、アプリ使用ログを集計して勤怠システム上の時間と乖離がないか確認したり...。
    国内外様々な企業の管理者様が、自社の要件に基づいて素晴らしい仕組みを構築されています。

    そんなJamf ProのAPIですが、認証方法変更のアナウンスに伴い、一部手直しが必要になってきましたので、今回はそちらの作業を行っていきたいと思います。

    ※APIをご利用されていない方にはまったく関係の無い、正直かなりニッチな内容ですがご興味ある方はお付き合い頂ければ幸いです...!

    【2024年5月28日 追記】
    Jamf Pro Classic APIにおけるBasic認証は2024年3月に廃止され、11.5へのアップグレード時に自動的にオフに変更となっています。(設定 > ユーザアカウントとグループ > パスワードポリシー > Classic API に Basic 認証を許可)
    重要なお知らせ - Jamf Pro リリースノート 11.5.0 | Jamf

    本ブログでご紹介しているBearer認証、あるいはAPIロールとクライアントを使用した認証が必要となりますのでご注意ください!

    はじめに

    まず、今回手直しする必要があるのは「Classic API」と呼ばれるインターフェースを使用している場合になります。

    ※Jamf ProにはClassic APIとJamf Pro API、2種類のAPIがあります。両者の違いについては、以下のページをご参照ください。

    Jamf Pro - Jamf Developer Portal | Jamf外部サイト

    Classic APIではこれまで「Basic認証」と呼ばれる認証方式をサポートしていましたが、2022年8~12月を目安に廃止が予定されており、順次「Bearer(ベアラー)認証」に置き換えていく必要があります。

    ※案内自体は2022年1月にリリースされたJamf Pro 10.35.0からされていましたが、いよいよ廃止時期が近づいてきたため、今回実際に試していくという次第です。

    廃止および削除 - Jamf Pro リリースノート | Jamf外部サイト Classic API Authentication Changes外部サイト

    設定

    それでは、「Bearer(ベアラー)認証」の設定を進めていきましょう。

    ステップ1:Basic認証について(前提の確認)

    まずは前提の確認です。
    Basic認証では、Jamf Proユーザアカウントとグループの情報を用いて認証を行っていました。以下のような形でスクリプト内に情報を記述します。

    #!/bin/bash

    jssURL="https://xxxxxx.jamfcloud.com"
    apiUsername="USERNAME"
    apiPassword="PASSWORD"

    ※余談ですが、Jamf Proのポリシー機能でスクリプトを展開する場合、パラメータを活用して以下のように定義することも可能です。スクリプト内にユーザ情報を平文で記述したくない!という場合にオススメです。

    #!/bin/bash

    jssURL="https://xxxxxx.jamfcloud.com"
    apiUsername="$4"
    apiPassword="$5"


    001.png

    また、指定するユーザの権限はJamf Pro側でカスタマイズすることが可能です。
    例えば、前段でご紹介させて頂いたアプリ使用ログを集計する場合であれば、コンピュータのインベントリ情報を読み取りできれば良いだけですので、Jamf Proのシステム設定 > Jamf Proユーザアカウントとグループ>権限タブから以下の画像のように設定します。

    002.png

    ※APIエンドポイントごとに必要な権限については以下のページをご参照ください。

    Jamf Pro APIPrivileges and Deprecations
    Classic APIPrivilege Requirements

    ステップ2:Bearer認証への置き換え

    それでは、実際に置き換え作業を行っていきます。

    まずはJamf Pro > 設定 > システム > APIロールとクライアント にアクセスします。
    先述のドキュメントを参照し、Jamf Pro API / Classic APIのエンドポイントごとに必要な権限を含むAPIロールを作成してください。(添付では後述の活用事例にあわせて「Read Computers」の権限を許可しています。)

    新規APIロール

    次に「APIクライアント」タブに移動し、先ほど保存したAPIロールを含むAPIクライアントを作成します。
    「Enable API client」ボタンをクリックして保存した後、「クライアントシークレットを生成」ボタンをクリックします。
    生成されたシークレット値は添付の画面以降表示されないため、クライアントIDを併せて安全な場所に控えておいてください。

    クライアントシークレットを保存

    その後、発行したクライアントIDとシークレット、およびJamf Pro APIの/v1/oauth/token エンドポイントを使用して、下記の形式にてアクセストークンを取得します。

    #!/bin/bash

    # 変数
    jssURL="https://○○○○.jamfcloud.com"
    clientId="1234abc5-d67e-890f-12gh-3i456jk78l90"
    clientSecret="ABcDeFGhijkLmNopQRStU1v2W3xYzA4Bc5DEFG6h78ijKLm9noPq-Rstuvwxy0ZA"

    # トークン取得
    response=$(curl --silent --location --request POST "${jssURL}/api/v1/oauth/token" \
     --header "Content-Type: application/x-www-form-urlencoded" \
     --data-urlencode "grant_type=client_credentials" \
     --data-urlencode "client_id=${clientId}" \
     --data-urlencode "client_secret=${clientSecret}")
    accessToken=$(echo "$response" | plutil -extract access_token raw -)

    ※ 変数に代入する赤字箇所は実際に使用する値に置き換えてください。ポリシーで展開する場合は、ステップ1と同様に変数を「"$4"」「"$5"」のように定義しても大丈夫です。

    こちらのスクリプトを実行すると、変数「accessToken」には以下のような情報が代入されています。(一部の文字を変更しています。)

    スクリーンショット 2022-06-15 16.55.00.png

    このトークンの有効期限は、先ほど「APIクライアント」タブで作成した設定によって定義されています。サンプルではデフォルト値の60秒に設定されているため、クライアントIDとシークレットを使用して都度新しいトークンを入手する形を想定しています。

    後は、このトークンを使用して後続のAPIエンドポイントを実行します。例えば特定のコンピュータがどのグループに含まれているかやどのポリシーが配布対象となっているかなどの管理情報を確認する場合は以下のような形で記述できます。

    #!/bin/bash

    # 変数
    serialNumber=$(system_profiler SPHardwareDataType | awk '/Serial/ {print $4}')
    jssURL="https://○○○○.jamfcloud.com"
    clientId="1234abc5-d67e-890f-12gh-3i456jk78l90"
    clientSecret="ABcDeFGhijkLmNopQRStU1v2W3xYzA4Bc5DEFG6h78ijKLm9noPq-Rstuvwxy0ZA"

    # トークン取得
    response=$(curl --silent --location --request POST "${jssURL}/api/v1/oauth/token" \
     --header "Content-Type: application/x-www-form-urlencoded" \
     --data-urlencode "grant_type=client_credentials" \
     --data-urlencode "client_id=${clientId}" \
     --data-urlencode "client_secret=${clientSecret}")
    accessToken=$(echo "$response" | plutil -extract access_token raw -)

    # コンピュータの管理情報を取得
    curl -s -X GET "${jssURL}/JSSResource/computermanagement/serialnumber/${serialNumber}" -H "authorization: Bearer ${accessToken}" | xmllint --format -

    活用事例(直近1週間のMac利用時間を集計)

    ...というわけで本題は終了してしまったのですが、これだけでは内容が少し寂しい気もするので、最後に今回のBearer認証を使用した実際の活用事例を記載させて頂きます。

    基本的には、前段でご紹介させて頂いたアプリ使用ログを集計する記事と同じ内容なのですが、そこではGAS(Google Apps Script)を活用して、Googleスプレッドシートにまとめる手法が解説されていました。

    ですが、お客様によってはGoogleサービスをご利用されていないケースもあるかと思います。

    今回は、
    ①Jamf Proの拡張属性にて直近1週間のMac利用時間をインベントリ情報として収集
    ②その情報を条件にスマートグループでしきい値を定義
    これによって、しきい値超えている(=働き過ぎ)なユーザをピックアップする形式で行こうと思います。

    まず、拡張属性に定義するスクリプトは以下のとおりです。

    ※今回は直近1週間で収集していますが、例えば1ヶ月とする場合は変数startDate(8行目)の部分を「date -v-1m ‘+%Y-%m-%d'」に変更してください。

    #!/bin/bash

    # 変数
    serialNumber=$(system_profiler SPHardwareDataType | awk '/Serial/ {print $4}')
    jssURL="https://○○○○.jamfcloud.com"
    clientId="1234abc5-d67e-890f-12gh-3i456jk78l90"
    clientSecret=“ABcDeFGhijkLmNopQRStU1v2W3xYzA4Bc5DEFG6h78ijKLm9noPq-Rstuvwxy0ZA"
    startDate=$(date -v-1w '+%Y-%m-%d')
    endDate=$(date '+%Y-%m-%d')

    # トークン取得
    response=$(curl --silent --location --request POST "${jssURL}/api/v1/oauth/token" \
     --header "Content-Type: application/x-www-form-urlencoded" \
     --data-urlencode "grant_type=client_credentials" \
     --data-urlencode "client_id=${clientId}" \
     --data-urlencode "client_secret=${clientSecret}")
    accessToken=$(echo "$response" | plutil -extract access_token raw -)

    # 直近1週間のMac利用時間(分)を集計
    foregroundList=$( curl -s -H "Accept: text/xml" -H "Authorization: Bearer ${accessToken}" "${jssURL}/JSSResource/computerapplicationusage/serialnumber/$serialNumber/${startDate}_${endDate}" | xmllint --format - | grep "foreground" | awk -F ">|<" '{ print $3 }' )

    totalMinutes=$( echo "$foregroundList" | awk '{ total += $0 } END { print total }' )
    echo "${totalMinutes}"

    ちなみに、スクリプトの実行結果は「2496」のように数字で返ってきますので、拡張属性のデータタイプは必ず「Integer」を選択してください。

    003.png

    次にスマートグループでしきい値を定義します。
    例えば1日の勤務時間を8時間、残業が4時間を超えている状態が継続していたら働き過ぎと仮定します。(本当はもっと早く上がるべきです...!)
    というわけで、以下のように(480+240)×5=3600分をCriteriaの数値に入力します。

    004.png

    あとは、こちらのスマートグループに誰かが含まれる際には、Slackに通知を飛ばす、デバイスにメッセージを表示するなどのアクションを検討します。

    Slackへの通知については以下の記事をご参照ください。

    Jamf Proからの通知をSlackで受け取る方法を考えてみました。 | @kajinari外部サイト

    メッセージを表示する手法は様々ありますが、以下の記事のようにjamfHelperを活用するのが良いかと思います。

    Marriott Library - Apple Infrastructure | Helping jamfHelper外部サイト

    こんな感じでメッセージが表示されます。

    005.png

    ※決してふざけているわけではないのです。こんなメッセージは目にする機会が無いのがイチバンですね...。

    まとめ

    いかがでしたでしょうか?
    冒頭にもお話させて頂きましたが、Jamf ProでAppleデバイスを管理するにあたり、APIの利用は必須ではありません。(むしろイレギュラーであることの方が多いです。)

    ですが、運用上の課題になっていることが場合によっては解決できるかもしれません。 もしお困り事や、今回の内容で気になることがございましたら、API利用要否の判断含めサポートさせて頂ければと思いますので、ぜひお気軽にお問い合わせください!

    記事は2022年6月16日現在の内容です。

    Apple Blog Topへ

    おすすめ記事を見る