{"templateId":"markdown","versions":[{"version":"v1.40","label":"v1.40 STS","link":"/products/custody/v1.40/concepts/ref_auth","default":true,"active":false,"folderId":"c15a2701"},{"version":"v1.39","label":"v1.39 STS","link":"/products/custody/v1.39/concepts/ref_auth","default":false,"active":false,"folderId":"c15a2701"},{"version":"v1.38","label":"v1.38 STS","link":"/products/custody/v1.38/concepts/ref_auth","default":false,"active":false,"folderId":"c15a2701"},{"version":"v1.34","label":"v1.34 LTS","link":"/products/custody/v1.34/concepts/ref_auth","default":false,"active":true,"folderId":"c15a2701"},{"version":"v1.26","label":"v1.26 LTS","link":"/products/custody/v1.26/concepts/ref_auth","default":false,"active":false,"folderId":"c15a2701"},{"version":"v1.19","label":"v1.19 LTS","link":"/products/custody/v1.19/concepts/ref_auth","default":false,"active":false,"folderId":"c15a2701"},{"version":"v1.15","label":"v1.15 LTS","link":"/products/custody/v1.15/concepts/ref_auth","default":false,"active":false,"folderId":"c15a2701"}],"sharedDataIds":{},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"API Authentication Flow Explained","description":"User guides, API reference, and support resources.","siteUrl":"https://docs.ripple.com","lang":"en-US","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"api-authentication-flow-explained","__idx":0},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["API Authentication Flow Explained"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This discussion provides a detailed technical explanation of the authentication flow required to use the ","Ripple Custody"," API, which is a key part of the \"Getting Started\" process for developers."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here is a summary of the concepts explained:"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"asymmetric-cryptography","__idx":1},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Asymmetric Cryptography"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The entire authentication system is built on public/private key cryptography (specifically Elliptic Curve Cryptography)."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Private Key:"]}," A secret key that the user possesses and never shares. Its only purpose is to sign data."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Public Key:"]}," A key that is shared publicly. Its purpose is to verify a signature created by the corresponding private key."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"the-authentication-flow","__idx":2},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["The Authentication Flow"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The process of proving your identity to the API involves several steps:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Genesis:"]}," First, the system must be initialized with a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Genesis block"]},". This configuration must include the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["public key"]}," of the initial admin user. This tells the system to \"trust\" this public key."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Get challenge:"]}," The user (or their custom application) generates a \"challenge,\" which is just a block of random data (e.g., 64 bytes)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Sign challenge:"]}," The user uses their ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["private key"]}," to create a cryptographic ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["signature"]}," of that challenge."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Authenticate:"]}," The user sends their ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["public key"]},", the original ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["challenge"]},", and the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["signature"]}," to the authentication endpoint."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Verification:"]}," The server performs two checks:",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["It uses the provided public key to verify that the signature is valid for the challenge."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["It checks if that public key is in its list of trusted keys (from the Genesis block)."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Get token:"]}," If both checks pass, the server has proof that the user owns the private key. It then issues a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["JSON Web Token (JWT)"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Make API calls:"]}," This ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["JWT"]}," (not the private key or signature) is then used as a Bearer token in the authorization header for all subsequent API calls to the platform."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"key-types-a-source-of-complexity","__idx":3},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key Types (A Source of Complexity)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The speaker notes that the platform supports three different types of cryptographic keys (P-256/R1, secp256k1/K1, and ED25519). This is a key technical detail as developers must ensure they are using the correct type."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"client-applications","__idx":4},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Client Applications"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This same authentication flow is used by all clients:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Ripple's Web App & Mobile App:"]}," They perform this challenge-and-signature flow internally."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Custom Client Backends:"]}," A client building a custom application (like a trading desk) would use this same flow (with a machine-to-machine grant type) to authenticate their own backend service."]}]}]},"headings":[{"value":"API Authentication Flow Explained","id":"api-authentication-flow-explained","depth":1},{"value":"Asymmetric Cryptography","id":"asymmetric-cryptography","depth":2},{"value":"The Authentication Flow","id":"the-authentication-flow","depth":2},{"value":"Key Types (A Source of Complexity)","id":"key-types-a-source-of-complexity","depth":2},{"value":"Client Applications","id":"client-applications","depth":2}],"frontmatter":{"seo":{"title":"API Authentication Flow Explained"}},"lastModified":"2026-04-07T19:14:09.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/products/custody/v1.34/concepts/ref_auth","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}