業務システム

Power BI Embeddedの実装手順:埋め込みトークンの発行とRLS・A SKU容量の選び方

Power BI Embeddedの実装手順:埋め込みトークンの発行とRLS・A SKU容量の選び方

Power BI Embeddedは、Power BIで作ったレポートを自社のWebアプリやSaaSの画面に組み込むためのAzureのサービスです。閲覧する顧客にPower BIのライセンスを持たせずに済む一方、サーバー側で埋め込みトークンを発行し、顧客ごとに見えるデータを絞る実装はアプリ側の責任になります。この記事では、サービスプリンシパルの準備からGenerateToken APIを呼ぶPythonのコード、ブラウザでの表示とトークン更新、マルチテナントでのRLSとワークスペース分離、A SKUの東日本リージョンの時間単価までを作業の順に示します。仕様の根拠は2026年11月時点のMicrosoft Learnの記述です。

まとめ:Power BI Embeddedはサーバーで埋め込みトークンを発行しA SKUで本番に載せる

顧客向けに埋め込むなら「アプリ所有データ」方式を選びます。サービスプリンシパルでMicrosoft Entraのトークンを取り、GenerateToken APIで埋め込みトークンを発行し、ブラウザのpowerbi-clientに渡す流れです。秘密情報はすべてサーバーに置き、ブラウザには有効期限つきの埋め込みトークンだけを渡します。

顧客ごとのデータ分離は、トークンに入れるidentitiesで決まります。顧客が数十社までなら1つのモデルに動的RLSを掛ける構成で対応が可能です。数千社規模ならワークスペースを顧客ごとに分けます。容量は本番で必須で、東日本のA1は1時間あたり約1.01ドル、24時間動かすと月735ドル前後です。閲覧が業務時間に限られるSaaSでなければ一時停止による節約はほぼ効かないため、月額の固定費として見積もります。

Power BI Embeddedのアプリ所有データ方式と、2種類のトークンの受け渡し順序

Power BIの埋め込みには、閲覧者が誰かによって2つの方式があります。どちらを選ぶかで、閲覧者のライセンスと使うトークンの種類が変わります。

顧客向けのアプリ所有データと組織向けのユーザー所有データで変わるライセンス要件

社外の顧客に見せる「顧客向けの埋め込み(アプリ所有データ)」では、アプリがPower BIへの認証を肩代わりします。Microsoft Learnの容量とSKUの解説には、この方式ではエンドユーザーのライセンス要件がないと書かれています。

社員が自分のMicrosoft Entraアカウントでサインインして見る「組織向けの埋め込み(ユーザー所有データ)」は別物です。F64未満の容量とA SKUでは、閲覧者ごとにProかPremium Per User(PPU)のライセンスが要ります。自社SaaSの顧客に見せるのが目的なら、検討対象はアプリ所有データ方式だけで十分です。製品全体の料金体系はPower BIのできることと料金・他ツールとの違いで整理しています。

Entraトークンから埋め込みトークンを作りブラウザへ渡すまでの4段階の流れ

アプリ所有データ方式では、性質の違う2つのトークンを順に使います。

  1. バックエンドがサービスプリンシパルの資格情報でMicrosoft EntraのアクセストークンをMSAL等で取得する
  2. そのトークンでレポート情報を取得するAPIを呼び、embedUrlとセマンティックモデルのIDを得る
  3. 同じトークンでGenerateToken APIを呼び、顧客のIDとロールを入れた埋め込みトークンを発行する
  4. フロントエンドが埋め込みトークンとembedUrlを受け取り、powerbi-clientでiframeに表示する

Entraのトークンはワークスペース全体を操作できる強い権限を持つため、ブラウザに出してはいけません。ブラウザに渡すのは、対象のレポートとデータに絞られた埋め込みトークンだけです。

サービスプリンシパルを作りワークスペースとテナント設定で権限を通す準備作業

トークンを発行する主体には、マスターユーザー(実在のProユーザー)とサービスプリンシパルの2つがあります。パスワードや多要素認証に左右されないサービスプリンシパルを選びます。

Entraアプリ登録とセキュリティグループ、APIのアクセス許可を足さない理由

サービスプリンシパルでの埋め込み手順は、Entraアプリの作成、セキュリティグループの作成、Power BI管理者設定の有効化、ワークスペースへの追加の順です。アプリを登録したら、アプリケーションIDとシークレット(本番では証明書が推奨)を控え、作ったセキュリティグループにサービスプリンシパルを入れます。

Azure portalの「APIのアクセス許可」には何も足しません。同ページは、Power BI REST API用のアプリに委任・アプリケーションの許可を追加しないよう勧めており、追加すると原因の追いにくいエラーを招くと注意しています。権限はPower BI側のテナント設定とワークスペースのロールで与えます。

管理ポータルの開発者向け設定2項目とワークスペースへのメンバー追加の手順

Power BI管理者が、管理ポータルの[テナントの設定]にある[開発者向け設定]で次の2つを、作成したセキュリティグループに対して有効にします。

  • アプリにコンテンツを埋め込む
  • Power BI API の使用をサービス プリンシパルに許可

続いて、埋め込むレポートのワークスペースにサービスプリンシパルかそのグループを「メンバー」か「管理者」で追加します。マイワークスペースは対象外で、埋め込み用には共有ワークスペースを作ります。テナント設定の画面とサービスプリンシパルでREST APIを呼ぶ準備は、Power BIのAPI連携の手順のサービスプリンシパル章と共通です。

GenerateToken APIによる埋め込みトークン発行のPython実装

ここからは埋め込みトークンの発行を担うPythonバックエンドの実装コードです。例はPythonですが、要求の形は言語を問いません。MicrosoftのPowerBI-Developer-Samplesには、.NET・Java・Node.js・Python・React(TypeScript)のアプリ所有データのサンプルがあります。

MSALによるEntra認証とembedUrl・埋め込みトークンの応答コード

モデル側には、あらかじめPower BI DesktopでTenantFilterというロールを作り、DAXで[TenantKey] = USERNAME()と定義しておきます。次の関数は、顧客の識別子を受け取り、その顧客の行だけが見える埋め込みトークンを返します。

import json, os, urllib.request
import msal

API = "https://api.powerbi.com/v1.0/myorg"
app = msal.ConfidentialClientApplication(
    os.environ["PBI_CLIENT_ID"],
    authority="https://login.microsoftonline.com/" + os.environ["PBI_TENANT_ID"],
    client_credential=os.environ["PBI_CLIENT_SECRET"],
)

def call(method, url, token, body=None):
    data = json.dumps(body).encode() if body is not None else None
    req = urllib.request.Request(url, data=data, method=method, headers={
        "Authorization": "Bearer " + token,
        "Content-Type": "application/json",
    })
    with urllib.request.urlopen(req, timeout=30) as r:
        return json.load(r)

def embed_config(ws_id, report_id, tenant_key):
    tok = app.acquire_token_for_client(
        scopes=["https://analysis.windows.net/powerbi/api/.default"])
    if "access_token" not in tok:
        raise RuntimeError(tok.get("error_description"))
    at = tok["access_token"]

    # レポートの embedUrl と、紐づくセマンティックモデルのIDを取る
    rep = call("GET", f"{API}/groups/{ws_id}/reports/{report_id}", at)

    body = {
        "reports": [{"id": report_id}],
        "datasets": [{"id": rep["datasetId"]}],
        "identities": [{
            "username": tenant_key,          # USERNAME() に渡る値
            "roles": ["TenantFilter"],
            "datasets": [rep["datasetId"]],
        }],
        "lifetimeInMinutes": 60,
    }
    et = call("POST", f"{API}/GenerateToken", at, body)
    return {"reportId": report_id, "embedUrl": rep["embedUrl"],
            "token": et["token"], "expiration": et["expiration"]}

tenant_keyは、ログイン中のユーザーのセッションからサーバー側で引きます。リクエストのクエリや本文で受け取った値をそのまま入れると、他社のキーを送るだけで他社のデータが見えてしまいます。GenerateToken APIのリファレンスによれば、usernameは256文字までで空白を含められず、1つのIDに入れられるロールは50個までです。

lifetimeInMinutesとEntraトークン残存時間による期限の制約

埋め込みトークンの有効期限には落とし穴があります。埋め込みトークン生成の考慮事項には、埋め込みトークンの有効期間は、GenerateTokenの呼び出しに使ったEntraトークンの残りの有効期間に設定されると書かれています。

Entraのトークンは約1時間で切れ、MSALはキャッシュ済みのトークンを返すことがあります。発行のたびに残り時間が減るため、50分前に取ったEntraトークンで発行した埋め込みトークンは10分ほどしか持ちません。lifetimeInMinutesは期限を縮めるためのパラメーターで、延ばすことはできません。フロントエンドは応答のexpirationを信じて更新時刻を決め、固定の「60分」を前提にしないことです。

powerbi-clientでレポートを画面に表示し期限切れ前にトークンを差し替える実装

ブラウザ側は、Microsoftが公開しているJavaScriptライブラリpowerbi-clientを使います。iframeの生成とトークンの受け渡しはこのライブラリが受け持ちます。

models.TokenType.Embedでの埋め込みとフィルターペイン非表示

バックエンドにembed-configのようなエンドポイントを作り、前のコードの戻り値をJSONで返す前提です。

import { models, service, factories } from "powerbi-client";

const powerbi = new service.Service(
  factories.hpmFactory, factories.wpmpFactory, factories.routerFactory);

async function showReport(container) {
  const cfg = await (await fetch("/api/embed-config")).json();
  const report = powerbi.embed(container, {
    type: "report",
    id: cfg.reportId,
    embedUrl: cfg.embedUrl,
    accessToken: cfg.token,
    tokenType: models.TokenType.Embed,   // アプリ所有データでは Embed
    settings: {
      panes: { filters: { visible: false } },
    },
  });
  report.on("error", (e) => console.error(e.detail));
  return { report, expiration: cfg.expiration };
}

レポートの埋め込み解説のとおり、tokenTypeはアプリ所有データではmodels.TokenType.Embed、組織向けではmodels.TokenType.Aadです。ここを取り違えると、トークン自体は正しくても表示に失敗します。フィルターペインを隠すのは見た目の調整で、権限の制御ではありません。見せてはいけない行は、前章のRLSで落とします。

setAccessTokenで期限10分前に再発行する更新処理と自動更新が使えない理由

トークンが切れると、開いたままの画面で操作ができなくなります。アクセストークンの更新の解説は、期限の10分前を目安に新しいトークンを取り、setAccessTokenで差し替える例を載せています。

const MINUTES_BEFORE = 10;

function scheduleRefresh(report, expiration) {
  const wait = Date.parse(expiration) - Date.now() - MINUTES_BEFORE * 60 * 1000;
  setTimeout(async () => {
    const cfg = await (await fetch("/api/embed-config")).json();
    await report.setAccessToken(cfg.token);
    scheduleRefresh(report, cfg.expiration);
  }, Math.max(wait, 0));
}

powerbi-client 2.20.1以降にはaccessTokenProviderによる自動更新がありますが、同ページの制限事項に組織向け(ユーザー所有データ)のみ対応と明記されています。顧客向けでは上のように自前でトークンの更新処理を組み立てる実装が必要です。ブラウザのタブが長時間裏にあるとタイマーが遅れるため、visibilitychangeで表示に戻ったときにも期限を確かめると取りこぼしが減ります。

マルチテナントSaaSで顧客のデータを分ける、RLSとワークスペース分離の選び方

複数の顧客に同じレポートを見せるSaaSでは、データ分離の方式が設計の中心になります。埋め込み分析のセキュリティ解説は、規模に応じて単一モデルのRLSとワークスペース分離を使い分ける構成を示しています。

username関数の動的RLSとidentities省略時の全件表示リスク

顧客数が少ない段階では、全顧客のデータを1つのセマンティックモデルに入れ、前章のTenantFilterのような動的ロール1つで絞るのが手早い構成です。ロールは顧客数が増えても1つのままで、顧客の追加はデータの追加だけで済みます。

注意点は、IDを渡し忘れたときの挙動です。RLSを使った埋め込みの手順によると、ユーザー名とロールを指定しない場合、サービスプリンシパルではトークン生成が失敗します。マスターユーザーでは生成が成功し、データがフィルターされずに全件返る挙動です。マスターユーザー方式のまま本番に出すと、コードの1行の漏れが全顧客のデータ漏えいになります。サービスプリンシパルを選ぶ理由はここにもあります。

顧客が数千社規模ならサービスプリンシパルプロファイルでワークスペースを分ける構成

顧客が増えると、1つのモデルのサイズと更新時間が容量の上限に近づきます。その場合は顧客ごとにワークスペースとモデルを分けます。サービスプリンシパルプロファイルの構成解説によれば、サービスプリンシパル単体では1,000ワークスペースまでですが、プロファイルを作るとプロファイルごとに1,000まで扱え、1つのサービスプリンシパルが持てるプロファイルは最大100,000です。API呼び出し時にX-PowerBI-Profile-Idヘッダーで顧客のプロファイルを指定します。

比較軸 単一モデル+動的RLS 顧客別ワークスペース
向く顧客数 数十社まで 数百〜数千社
レポートの改修 1か所の発行で全社に反映 全ワークスペースへの再発行が要る
大口顧客だけ別容量 できない ワークスペース単位で割り当て可能
分離の根拠 トークンのidentities ワークスペースの権限とトークンの範囲

同じ解説は、プロファイルはMicrosoft EntraのIDではなくFabric REST APIでは使えないこと、新規のマルチテナント構成では顧客専用のサービスプリンシパルから始める選択肢もあることを注記しています。どちらの方式でも、ログイン中のユーザーが属する顧客をアプリ側で確かめてからプロファイルやIDを選ぶ処理は省けません。

A SKU・F SKU・P SKUの容量選びと、東日本リージョンA1の時間単価から見る月額

埋め込みの本番運用には容量の購入が必要です。開発段階から本番までの費用の動きを先に押さえておくと、見積もりのずれが減ります。

開発中の無料試用版トークンと本番で容量が要る境界、試用版バナーの扱い

開発とテストの間は、Proライセンスで無料の埋め込み試用版トークンを使えます。容量とSKUの解説によれば、試用版トークンは開発テスト専用で、容量を購入するまで埋め込みレポートの上部に「無料試用版」のバナーが表示され続ける仕様です。顧客に見せるデモの前に容量を割り当てておかないと、このバナーが出たままになります。

レポートの発行にはProかPPUのアカウントが要りますが、サービスプリンシパルがPost Import In Groupで発行する場合はライセンスなしで発行できます。発行の自動化はREST APIで更新・発行を自動化する手順で扱っています。

A1〜A6の時間単価と、夜間の一時停止で課金を止める運用の前提条件

Azureの公開価格APIで東日本リージョン(japaneast)のA SKUを2026年11月8日に取得した単価です。月額は730時間動かし続けた場合の概算で、円建ての最新値はAzure公式の価格ページで確かめてください。

SKU 仮想コア 同等のF SKU 1時間あたり(USD) 730時間の概算(USD)
A1 1 F8 1.0081 約736
A2 2 F16 2.0081 約1,466
A3 4 F32 4.0242 約2,938
A4 8 F64 8.0565 約5,881
A5 16 F128 16.121 約11,768
A6 32 F256 32.2506 約23,543

A SKUは時間課金でコミットがなく、スケールの変更と一時停止ができます。一時停止と開始の手順には、一時停止中は課金されないこと、ただしコンテンツが使えなくなる可能性があるため先にワークスペースの割り当てを外すよう書かれています。PowerShellで容量の一時停止とその後の再開を行う場合は、次の2行のコマンドを使う手順です。

Suspend-AzPowerBIEmbeddedCapacity -Name pbiemb01 -ResourceGroupName rg-analytics
Resume-AzPowerBIEmbeddedCapacity -Name pbiemb01 -ResourceGroupName rg-analytics

止めている間は顧客もレポートを開けません。平日10時間×22日だけ動かせばA1で月220ドル前後に下がりますが、成り立つのは開発・検証環境か、利用時間が契約で決まっている社内向けポータルに限られます。24時間使われるSaaSの本番は止めない前提で見積もり、開発用の容量を別に用意して止める運用が現実的です。

Power BI Embeddedの採用条件と自前のグラフ実装・OSSの選択基準

実装の手間と月額の固定費を踏まえ、採用と見送りの条件を言い切ります。複数製品をまたぐ方式の比較は組み込み分析の実装方式4種と内製・外注の判断基準にまとめています。

採用が見合う条件はモデルが既にあり顧客が集計軸を自分で変えたい場合

採用してよいのは、次の2つが両方そろう場合です。1つは、社内でPower BIのセマンティックモデルとレポートが既に動いていて、それを顧客向けに出したい場合です。モデル設計とDAXの資産をそのまま使えるため、画面の開発工数がほぼかかりません。もう1つは、顧客がスライサーやドリルダウンで集計軸を自分で切り替えたい要望を持っている場合です。グラフを自前で実装すると、軸の追加のたびに開発が発生します。

この2つがそろい、月数百ドルの固定費を顧客単価に乗せられるなら、Power BI Embeddedが最短です。

見送る場面と、トークン発行・RLS設計を外部に任せる範囲の目安

見送るのは、表示するグラフが数枚で集計軸がほぼ固定の場合です。売上推移と件数の棒グラフ程度なら、Chart.js等で描くほうが固定費がかからず、画面の見た目も製品に合わせやすくなります。顧客が月に数回しか開かない機能に、A1でも月700ドル以上を払い続けるのは過剰です。Power BIのモデルを持っておらず一から作る場合も、OSSのBIを含めて比較してから決めます。

採用を決めた後に詰まりやすいのは、トークン発行のエンドポイントの認可、顧客キーとRLSロールの対応づけ、顧客増加時のワークスペース分離への移行の3か所です。社内にPower BIのモデル担当はいても、Webアプリの認可とAzureの構成を担える人がいない場合は、この部分を切り出して外部に任せると立ち上げが早まります。一創のBIツール導入支援では、モデル設計から自社アプリへの埋め込みまでをご相談いただけます。

Power BI Embeddedの料金や埋め込みトークンの実装でよくある質問

導入前の検討と実装の途中で出やすい質問に、Microsoft Learnの記述をもとに答えます。

Power BI Embeddedで埋め込んだレポートの閲覧者にProライセンスは必要ですか?

顧客向けの埋め込み(アプリ所有データ)なら不要です。閲覧者はPower BIのアカウントを持たず、アプリが発行した埋め込みトークンで表示します。社員が自分のEntraアカウントで見る組織向けの埋め込みでは、F64未満の容量とA SKUの場合、閲覧者ごとにProかPPUが必要です。なお、レポートを発行する作成者にはProかPPUが要ります(サービスプリンシパルでのAPI発行を除く)。

Power BI Embeddedは容量を買う前に無料で試せますか?

試せます。Proライセンスがあれば、容量なしで無料の埋め込み試用版トークンを発行でき、開発とテストに使えます。ただし用途は開発テストに限られ、埋め込んだレポートの上部には「無料試用版」のバナーが継続して表示される仕様です。顧客に見せる段階では、A SKUなどの容量を購入してワークスペースに割り当てます。

A SKUとF SKUは、顧客向けの埋め込みではどちらを買うべきですか?

どちらもアプリ所有データの埋め込みに使えます。埋め込みだけが目的で、時間単位で課金を止めたい開発環境があるならA SKUが扱いやすい選択です。データの取り込みや加工にMicrosoft Fabricの他の機能も使う予定なら、同じ容量で賄えるF SKUを検討します。演算能力はA1とF8、A4とF64が同等です。F SKUの一時停止はFabric側の手順で行います。

埋め込みトークンの有効期限を1時間より長く延ばすことはできますか?

できません。GenerateToken APIのlifetimeInMinutesは期限を縮めるためのもので、延長には使えません。さらに埋め込みトークンの期限は、発行に使ったEntraトークンの残り時間に揃えられます。長時間開かれる画面では、応答のexpirationの10分前を目安に新しいトークンを取り、setAccessTokenで差し替えます。

ReactやNext.jsで作った自社アプリにもPower BIのレポートを埋め込めますか?

埋め込めます。表示はpowerbi-clientというJavaScriptライブラリが担うため、フレームワークを問いません。MicrosoftのPowerBI-Developer-SamplesにはReact(TypeScript)のサンプルも含まれています。Next.jsの場合は、埋め込みトークンの発行をサーバー側のAPIルートに置き、サービスプリンシパルのシークレットがクライアントのバンドルに入らないようにします。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.11.03 テックブログ ネットマイル不正アクセスで最大549万人:対象確認と退会会員データを消す実装
  2. 2026.11.06 テックブログ ドコモ不正アクセス:最大29.5万件の流出項目と見舞金、My docomo停止の経過と偽連絡の見分け方
  3. 2026.11.06 テックブログ あいおいニッセイ同和の不正アクセス:44.4万件の漏えい項目と窓口、止まった手続きの代わり
  4. 2026.11.06 テックブログ アイリスオーヤマ情報漏洩:アイリスプラザ770万人分の対象項目と本物の連絡の見分け方
  5. 2026.07.09 テックブログ Muse Imageとは?Metaの画像生成AIの使い方・API料金(1枚0.01ドル)と日本での提供状況【2026年10月】

RELATED POSTS 関連記事

目次