PageSourceSearch

https://opentdf.io/assets/js/2ca69888.5408263d.js

js opentdf.io collected 2026-10-08 04:15:07 UTC 21,188 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkdocs=globalThis.webpackChunkdocs||[]).push([[4788],{88612(e,t,n){n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"guides/authentication-guide","title":"Authentication Decision Guide","description":"How to choose the right authentication method for your integration, based on your environment and use case.","source":"@site/docs/guides/authentication-guide.mdx","sourceDirName":"guides","slug":"/guides/authentication-guide","permalink":"/guides/authentication-guide","draft":false,"unlisted":false,"tags":[],"version":"current","lastUpdatedAt":1784124470000,"sidebarPosition":5,"frontMatter":{"title":"Authentication Decision Guide","sidebar_position":5},"sidebar":"tutorialSidebar","previous":{"title":"Subject Mapping Guide","permalink":"/guides/subject-mapping-guide"},"next":{"title":"Authorization REST API Guide","permalink":"/guides/authorization-rest-api"}}');var s=n(74848),r=n(28453);const o={title:"Authentication Decision Guide",sidebar_position:5},c="Authentication Decision Guide",a={},d=[{value:"How Authentication Works",id:"how-authentication-works",level:2},{value:"Choose Your Authentication Method",id:"choose-your-authentication-method",level:2},{value:"Scenario Matrix",id:"scenario-matrix",level:2},{value:"Getting Started",id:"getting-started",level:2},{value:"Client Credentials (Backend Services)",id:"client-credentials-backend-services",level:3},{value:"OIDC Login Flow (Browser Apps)",id:"oidc-login-flow-browser-apps",level:3},{value:"Token Exchange (Federated Identity)",id:"token-exchange-federated-identity",level:3},{value:"Certificate Exchange (mTLS)",id:"certificate-exchange-mtls",level:3},{value:"CLI Authentication",id:"cli-authentication",level:3},{value:"Development vs Production",id:"development-vs-production",level:2},{value:"Local Development",id:"local-development",level:3},{value:"Production Checklist",id:"production-checklist",level:3},{value:"Common Pitfalls",id:"common-pitfalls",level:2},{value:"&quot;I&#39;m getting 401 Unauthorized&quot;",id:"im-getting-401-unauthorized",level:3},{value:"&quot;My token expired and I&#39;m getting errors&quot;",id:"my-token-expired-and-im-getting-errors",level:3},{value:"&quot;DPoP-related errors&quot;",id:"dpop-related-errors",level:3},{value:"&quot;TLS/certificate errors&quot;",id:"tlscertificate-errors",level:3}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",input:"input",li:"li",mermaid:"mermaid",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"authentication-decision-guide",children:"Authentication Decision Guide"})}),"\n",(0,s.jsx)(t.admonition,{title:"What you'll learn",type:"info",children:(0,s.jsx)(t.p,{children:"How to choose the right authentication method for your integration, based on your environment and use case."})}),"\n",(0,s.jsx)(t.h2,{id:"how-authentication-works",children:"How Authentication Works"}),"\n",(0,s.jsxs)(t.p,{children:["The platform is a ",(0,s.jsx)(t.strong,{children:"resource server"})," \u2014 it does not manage user identities or issue tokens. Instead, you bring your own OIDC-compatible identity provider (IdP), such as ",(0,s.jsx)(t.a,{href:"https://www.keycloak.org/",children:"Keycloak"})," (the reference implementation), and configure the platform to trust it."]}),"\n",(0,s.jsx)(t.p,{children:"The authentication flow looks like this:"}),"\n",(0,s.jsx)(t.mermaid,{value:"sequenceDiagram\n    participant App as Your Application\n    participant IdP as Identity Provider\n    participant Platform as Platform\n\n    App->>IdP: Authenticate (credentials, token, cert)\n    IdP--\x3e>App: Access token (+ optional DPoP proof)\n    App->>Platform: API request with access token\n    Platform->>IdP: Validate token (OIDC discovery)\n    Platform--\x3e>App: Response"}),"\n",(0,s.jsxs)(t.p,{children:["Your choice of authentication method determines ",(0,s.jsx)(t.strong,{children:"how your application obtains tokens from the IdP"}),". The platform validates tokens against a trusted issuer, but a valid token alone is not sufficient \u2014 the token must also carry the correct audience (",(0,s.jsx)(t.code,{children:"aud"}),"), required claims, and scopes for the request to succeed."]}),"\n",(0,s.jsx)(t.h2,{id:"choose-your-authentication-method",children:"Choose Your Authentication Method"}),"\n",(0,s.jsx)(t.p,{children:"Use this flowchart to find the right method for your situation:"}),"\n",(0,s.jsx)(t.mermaid,{value:'flowchart TD\n    Start([What are you building?]) --\x3e Backend{Backend service<br/>or script?}\n    Backend --\x3e|Yes| ClientCreds[**Client Credentials**<br/>Most common choice]\n    Backend --\x3e|No| WebApp{Browser-based<br/>web app?}\n    WebApp --\x3e|Yes| Refresh[**OIDC Login Flow**<br/>JS SDK only]\n    WebApp --\x3e|No| CLI{CLI tool for<br/>interactive users?}\n    CLI --\x3e|Yes| OtdfCtl[**otdfctl auth login**<br/>Browser-based OIDC flow]\n    CLI --\x3e|No| CICD{CI/CD pipeline<br/>or automated job?}\n    CICD --\x3e|Yes| ClientCreds\n    CICD --\x3e|No| Federated{Federated identity<br/>or SAML?}\n    Federated --\x3e|Yes| TokenExchange[**Token Exchange**<br/>RFC 8693]\n    Federated --\x3e|No| MTLS{mTLS<br/>environment?}\n    MTLS --\x3e|Yes| CertExchange[**Certificate Exchange**]\n    MTLS --\x3e|No| Custom[**Custom Token Source**<br/>
1Bring your own provider]\n\n    click ClientCreds "/sdks/authentication#client-credentials"\n    click Refresh "/sdks/authentication#refresh-token"\n    click TokenExchange "/sdks/authentication#token-exchange"\n    click CertExchange "/sdks/authentication#certificate-exchange-mtls"\n    click Custom "/sdks/authentication#custom-token-source"'}),"\n",(0,s.jsx)(t.h2,{id:"scenario-matrix",children:"Scenario Matrix"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Scenario"}),(0,s.jsx)(t.th,{children:"Recommended Method"}),(0,s.jsx)(t.th,{children:"Notes"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Backend service / microservice"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/sdks/authentication#client-credentials",children:"Client Credentials"})}),(0,s.jsxs)(t.td,{children:["Most straightforward. Use ",(0,s.jsx)(t.code,{children:"clientCredentialsTokenProvider()"})," \u2014 it caches tokens and auto-refreshes on expiry."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Web application (browser) with refresh token"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/sdks/authentication#refresh-token",children:"Refresh Token"})}),(0,s.jsxs)(t.td,{children:["JS SDK only. Use ",(0,s.jsx)(t.code,{children:"refreshTokenProvider()"})," with a refresh token from your OIDC login flow. Handles automatic renewal."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Web application (browser) with access token only"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/sdks/authentication#access-token",children:"Access Token"})}),(0,s.jsxs)(t.td,{children:["JS SDK only. Use ",(0,s.jsx)(t.code,{children:"authTokenInterceptor()"})," with a function that returns your access token. Use when your IdP doesn't issue refresh tokens."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"CLI tool (interactive user)"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"otdfctl auth login"})}),(0,s.jsxs)(t.td,{children:["Opens a browser for OIDC login. See ",(0,s.jsx)(t.a,{href:"/components/cli/auth/login",children:"CLI auth docs"}),"."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"CI/CD pipeline / automated job"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/sdks/authentication#client-credentials",children:"Client Credentials"})}),(0,s.jsx)(t.td,{children:"Use a dedicated service account. Rotate secrets regularly."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Federated identity / SAML"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/sdks/authentication#token-exchange",children:"Token Exchange"})}),(0,s.jsx)(t.td,{children:"Exchange an existing token for one the platform accepts."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"mTLS environment"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/sdks/authentication#certificate-exchange-mtls",children:"Certificate Exchange"})}),(0,s.jsx)(t.td,{children:"Uses client certificates for transport-level auth."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Custom IdP integration"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/sdks/authentication#custom-token-source",children:"Custom Token Source"})}),(0,s.jsx)(t.td,{children:"Implement the token provider interface in your SDK."})]})]})]}),"\n",(0,s.jsx)(t.h2,{id:"getting-started",children:"Getting Started"}),"\n",(0,s.jsx)(t.h3,{id:"client-credentials-backend-services",children:"Client Credentials (Backend Services)"}),"\n",(0,s.jsxs)(t.p,{children:["The simplest path. Register a client in your IdP, then use ",(0,s.jsx)(t.code,{children:"clientCredentialsTokenProvider()"})," (JS) or pass the client ID and secret directly (Go/Java). The SDK handles token acquisition, caching, and refresh automatically."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"What you need:"})," A client ID and client secret from your IdP."]}),"\n",(0,s.jsxs)(t.p,{children:["See ",(0,s.jsx)(t.a,{href:"/sdks/authentication#client-credentials",children:"SDK code examples"})," for Go, Java, and JavaScript."]}),"\n",(0,s.jsx)(t.h3,{id:"oidc-login-flow-browser-apps",children:"OIDC Login Flow (Browser Apps)"}),"\n",(0,s.jsxs)(t.p,{children:["For browser-based applications, your app completes an ",(0,s.jsx)(t.a,{href:"https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth",children:"OIDC Authorization Code flow"})," to obtain an access token and (optionally) a refresh token from the IdP."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"If you have a refresh token"}),", use ",(0,s.jsx)(t.a,{href:"/sdks/authentication#refresh-token",children:(0,s.jsx)(t.code,{children:"refreshTokenProvider()"})}
1)," \u2014 it handles token exchange and automatic renewal."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"If you only have an access token"})," (because your IdP doesn't issue refresh tokens or the grant is disabled for security reasons), use ",(0,s.jsx)(t.a,{href:"/sdks/authentication#access-token",children:(0,s.jsx)(t.code,{children:"authTokenInterceptor()"})})," with a function that returns your token."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["See SDK code examples: ",(0,s.jsx)(t.a,{href:"/sdks/authentication#refresh-token",children:"Refresh Token"})," | ",(0,s.jsx)(t.a,{href:"/sdks/authentication#access-token",children:"Access Token"})," (JavaScript only)."]}),"\n",(0,s.jsx)(t.h3,{id:"token-exchange-federated-identity",children:"Token Exchange (Federated Identity)"}),"\n",(0,s.jsx)(t.p,{children:"When your application already has a token from another identity system (SAML, external JWT), use token exchange to swap it for a token the platform trusts."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"What you need:"})," A valid JWT or SAML assertion from the source identity system."]}),"\n",(0,s.jsxs)(t.p,{children:["See ",(0,s.jsx)(t.a,{href:"/sdks/authentication#token-exchange",children:"SDK code examples"})," for Go, Java, and JavaScript."]}),"\n",(0,s.jsx)(t.h3,{id:"certificate-exchange-mtls",children:"Certificate Exchange (mTLS)"}),"\n",(0,s.jsx)(t.p,{children:"In environments that require mutual TLS, the SDK can use client certificates to authenticate with the IdP."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"What you need:"})," A client certificate and private key, plus the CA certificate chain."]}),"\n",(0,s.jsxs)(t.p,{children:["See ",(0,s.jsx)(t.a,{href:"/sdks/authentication#certificate-exchange-mtls",children:"SDK code examples"})," for Go and Java."]}),"\n",(0,s.jsx)(t.h3,{id:"cli-authentication",children:"CLI Authentication"}),"\n",(0,s.jsxs)(t.p,{children:["For interactive command-line use, a platform CLI can handle the OIDC login flow for you. The OpenTDF CLI (",(0,s.jsx)(t.code,{children:"otdfctl"}),"):"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"# Interactive login (opens browser)\notdfctl auth login --endpoint http://localhost:8080\n\n# Non-interactive (for scripts)\notdfctl auth client-credentials --client-id my-client --client-secret my-secret\n\n# Print your current access token (useful for debugging)\notdfctl auth print-access-token\n"})}),"\n",(0,s.jsxs)(t.p,{children:["See the ",(0,s.jsx)(t.a,{href:"/components/cli/auth/login",children:"CLI auth command reference"})," for all options."]}),"\n",(0,s.jsx)(t.h2,{id:"development-vs-production",children:"Development vs Production"}),"\n",(0,s.jsx)(t.h3,{id:"local-development",children:"Local Development"}),"\n",(0,s.jsxs)(t.p,{children:["The OpenTDF ",(0,s.jsx)(t.a,{href:"/quickstart",children:"quickstart"})," runs Keycloak with pre-configured defaults:"]}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Setting"}),(0,s.jsx)(t.th,{children:"Default value"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Platform endpoint"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"http://localhost:8080"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"OIDC origin"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"http://localhost:8888/auth/realms/opentdf"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Client ID"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"opentdf"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Client secret"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"secret"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"TLS"}),(0,s.jsx)(t.td,{children:"Disabled (plaintext)"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"DPoP"}),(0,s.jsx)(t.td,{children:"Enabled"})]})]})]}),"\n",(0,s.jsx)(t.admonition,{type:"warning",children:(0,s.jsx)(t.p,{children:"These defaults are for development only. Do not use them in production."})}),"\n",(0,s.jsx)(t.h3,{id:"production-checklist",children:"Production Checklist"}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"The platform does not prescribe a specific deployment strategy. This checklist covers authentication-related concerns \u2014 your infrastru
1cture, scaling, and orchestration choices are up to you."})}),"\n",(0,s.jsxs)(t.ul,{className:"contains-task-list",children:["\n",(0,s.jsxs)(t.li,{className:"task-list-item",children:[(0,s.jsx)(t.input,{type:"checkbox",disabled:!0})," ",(0,s.jsx)(t.strong,{children:"Enable TLS"})," \u2014 All connections to the platform and IdP must use HTTPS"]}),"\n",(0,s.jsxs)(t.li,{className:"task-list-item",children:[(0,s.jsx)(t.input,{type:"checkbox",disabled:!0})," ",(0,s.jsx)(t.strong,{children:"Use strong client secrets"})," \u2014 Generate long, random secrets and store them securely (vault, environment variables \u2014 never in code)"]}),"\n",(0,s.jsxs)(t.li,{className:"task-list-item",children:[(0,s.jsx)(t.input,{type:"checkbox",disabled:!0})," ",(0,s.jsx)(t.strong,{children:"Rotate secrets regularly"})," \u2014 Automate secret rotation where possible"]}),"\n",(0,s.jsxs)(t.li,{className:"task-list-item",children:[(0,s.jsx)(t.input,{type:"checkbox",disabled:!0})," ",(0,s.jsx)(t.strong,{children:"Restrict scopes"})," \u2014 Request only the scopes your application needs"]}),"\n",(0,s.jsxs)(t.li,{className:"task-list-item",children:[(0,s.jsx)(t.input,{type:"checkbox",disabled:!0})," ",(0,s.jsx)(t.strong,{children:"Enable DPoP"})," \u2014 Sender-constrained tokens protect against token theft (see ",(0,s.jsx)(t.a,{href:"/sdks/authentication#dpop-sender-constrained-tokens",children:"DPoP docs"}),")"]}),"\n",(0,s.jsxs)(t.li,{className:"task-list-item",children:[(0,s.jsx)(t.input,{type:"checkbox",disabled:!0})," ",(0,s.jsx)(t.strong,{children:"Set appropriate token lifetimes"})," \u2014 Short-lived access tokens with refresh tokens where applicable"]}),"\n",(0,s.jsxs)(t.li,{className:"task-list-item",children:[(0,s.jsx)(t.input,{type:"checkbox",disabled:!0})," ",(0,s.jsx)(t.strong,{children:"Use a production-grade IdP"})," \u2014 Configure Keycloak (or your chosen IdP) for high availability, backups, and monitoring"]}),"\n",(0,s.jsxs)(t.li,{className:"task-list-item",children:[(0,s.jsx)(t.input,{type:"checkbox",disabled:!0})," ",(0,s.jsx)(t.strong,{children:"Configure CORS (browser-based apps)"})," \u2014 Your application's origin must be registered as an allowed origin in both the IdP and the platform"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"common-pitfalls",children:"Common Pitfalls"}),"\n",(0,s.jsx)(t.h3,{id:"im-getting-401-unauthorized",children:'"I\'m getting 401 Unauthorized"'}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Check your IdP URL."})," The platform discovers the IdP via its well-known OIDC endpoint. Verify the ",(0,s.jsx)(t.code,{children:"oidcOrigin"})," (JS), token endpoint (Go), or platform endpoint (Java) is correct."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Verify the client exists."})," Ensure the client ID is registered in your IdP and the secret matches."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Check token audience."})," The platform rejects tokens whose ",(0,s.jsx)(t.code,{children:"aud"})," claim doesn't match the expected audience. Decode your token (e.g., at ",(0,s.jsx)(t.a,{href:"https://jwt.io",children:"jwt.io"}),") and verify the ",(0,s.jsx)(t.code,{children:"aud"})," field matches what's configured in your platform's YAML config under the auth section."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Check CORS."})," For browser-based apps, your application's origin must be allowed in both the IdP and platform configuration. CORS errors often appear as opaque network failures rather than clear 401 responses."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"my-token-expired-and-im-getting-errors",children:'"My token expired and I\'m getting errors"'}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Client credentials:"})," The built-in ",(0,s.jsx)(t.code,{children:"clientCredentialsTokenProvider()"})," (JS) and Go/Java SDKs refresh automatically \u2014 if you're seeing expiry errors, check that your IdP is reachable."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"OAuth token source (Go):"})," ",(0,s.jsx)(t.code,{children:"WithOAuthAccessTokenSource"})," does not auto-refresh. Your ",(0,s.jsx)(t.code,{children:"TokenSource"})," implementation must handle refresh."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Refresh token (JS):"})," ",(0,s.jsx)(t.code,{children:"refreshTokenProvider()"})," handles rotation automatically, but ensure the initial refresh token itself hasn't expired. Long-lived refresh tokens can be configured in your IdP."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"dpop-related-errors",children:'"DPoP-related errors"'}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"IdP doesn't support DPoP:"})," Disable it with ",(0,s.jsx)(t.code,{children:"disableDPoP: true"})," (JS) or configure your IdP to accept DPoP proofs."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Clock skew:"})," DPoP proofs include a timestamp. Ensure your server and IdP clocks are synchronized (NTP)."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Key mismatch:"})," If you provide custom DPoP keys, ensure the same key pair is used for the lifetime of the session."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"tlscertificate-errors",children:'"TLS/certificate errors"'}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Self-signed certs in development:"})," Use ",(0,s.jsx)(t.code,{children:"useInsecurePlaintextConnection(true)"})," (Java) or configure your TLS settings to trust the development CA."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Missing CA certs:"})," Ensure the platform's CA certificate is in your trust store."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453(e,t,n){n.d(t,{R:()=>o,x:()=>c});var i=n(96540);const s={},r=i.createContext(s);function o(e){const t=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.