Rayfin

@microsoft/rayfin-embed-host

Parent-page SDK reference for brokering external Entra authentication into a Rayfin app embedded in an iframe.

New in 1.36

@microsoft/rayfin-embed-host is the parent-page SDK for embedding a Rayfin app in an iframe and brokering its external Entra authentication. The parent portal supplies a delegated Entra token; the iframe receives only a single-use handoff code.

Installation

npm install @microsoft/rayfin-embed-host

Exports

export { createEmbedHost };
export { EmbedHostError };
export type {
  EmbedHost,
  EmbedHostErrorCode,
  EmbedHostOptions,
  HandoffProvider,
  HandoffRequest,
  HandoffResult,
};

HandoffProvider is a contributor extension seam, not a Builder-facing API.

createEmbedHost

function createEmbedHost(options: EmbedHostOptions): EmbedHost;

Registers a message listener in the parent window. Call it before mounting or navigating the Rayfin iframe because the embedded app sends its readiness message once.

import { createEmbedHost } from '@microsoft/rayfin-embed-host';

const host = createEmbedHost({
  allowedOrigins: ['https://my-rayfin-app.example.com'],
  getAccessToken: () => acquireDelegatedEntraToken(),
});

host.dispose();

createEmbedHost() throws a Rayfin SdkError if called outside a browser environment.

EmbedHostOptions

interface EmbedHostOptions {
  allowedOrigins: string[];
  getAccessToken: () => string | Promise<string>;
  handoffProvider?: HandoffProvider;
}
OptionTypeDescription
allowedOriginsstring[]Exact origins of embedded Rayfin apps this host will broker for. The same list gates the iframe sender origin and the return origin bound into the handoff code.
getAccessToken() => string | Promise<string>Returns the parent portal's delegated Entra access token. Called once per handoff request and never cached by the host.
handoffProviderHandoffProviderInternal acquisition seam. Omit in application code.

Use origins only, such as https://my-rayfin-app.example.com. Do not include paths.

EmbedHost

interface EmbedHost {
  dispose(): void;
}

dispose() removes the parent-window message listener and stops brokering handoffs. It is idempotent.

Wire protocol behavior

The host handles two message families on channel fabric-auth:

MessageDirectionPurpose
externalEmbed.readyiframe to parentOne-shot readiness announcement.
externalEmbed.ackparent to iframeScenario acknowledgement declaring externalEmbed.
auth.requestHandoffiframe to parentCorrelated handoff request with PKCE challenge, return origin, brokered-authorize endpoint, and artifact ID.
responseparent to iframeCorrelated success or error response.

The host ignores readiness and handoff messages from origins outside allowedOrigins. Handoff requests must come from the same window and origin that completed readiness.

HandoffRequest and HandoffResult

interface HandoffRequest {
  brokeredAuthorizeUrl: string;
  artifactId: string;
  returnOrigin: string;
  codeChallenge: string;
  codeChallengeMethod: string;
  state?: string;
  getAccessToken: () => string | Promise<string>;
}

interface HandoffResult {
  handoffCode: string;
  state?: string;
}

The default provider posts to brokeredAuthorizeUrl with:

  • Authorization: Bearer <delegated Entra token>
  • x-ms-workload-resource-moniker: <artifactId>
  • JSON body containing returnOrigin, PKCE challenge fields, and optional state

The delegated token is never sent over postMessage.

EmbedHostError

type EmbedHostErrorCode =
  | 'EXCHANGE_NOT_ENABLED'
  | 'AUTH_FAILED'
  | 'INSUFFICIENT_PERMISSIONS'
  | 'NOT_AVAILABLE'
  | 'AUTHORIZE_FAILED'
  | 'VALIDATION_FAILED';

class EmbedHostError extends SdkError {
  readonly code: EmbedHostErrorCode;
}
CodeMeaning
EXCHANGE_NOT_ENABLEDThe target app has not enabled external Entra exchange.
AUTH_FAILEDThe delegated Entra token was rejected.
INSUFFICIENT_PERMISSIONSThe user lacks Execute permission on the item.
NOT_AVAILABLEThe brokered-authorize endpoint is unavailable or wrong.
AUTHORIZE_FAILEDNetwork failure, malformed response, missing handoff code, or an unrecognized endpoint status.
VALIDATION_FAILEDThe handoff request failed host-side validation before any network call.

Messages are safe to log and do not include the delegated token or raw response body.

Default error messages

CodeMessage
VALIDATION_FAILEDreturnOrigin is not permitted by the embed host.
AUTHORIZE_FAILEDFailed to broker the authentication handoff.
AUTHORIZE_FAILEDFailed to reach the brokered-authorize endpoint.
AUTHORIZE_FAILEDBrokered-authorize endpoint returned a malformed response.
AUTHORIZE_FAILEDBrokered-authorize endpoint returned no handoff code.
EXCHANGE_NOT_ENABLED, AUTH_FAILED, INSUFFICIENT_PERMISSIONS, NOT_AVAILABLE, AUTHORIZE_FAILEDBrokered-authorize endpoint responded with status <status>.

Browser requirements

This package runs in a parent browser window. It uses window.addEventListener('message', ...), postMessage, and fetch. It is not for Node.js.

Something wrong on this page?Report an issueEdit this page

On this page