Step-by-step implementation
You can configure delegated access entirely on the client side using the Turnkey SDKs — @turnkey/react-wallet-kit for React apps, or @turnkey/core for other frontend frameworks. This works whether you use the Auth Proxy or your own backend to provision the sub-organization and issue the user’s authenticated session. Both approaches follow the same principle — using an authenticated session to add a Delegated Access (DA) user and defining policies for that user within the sub-organization.Step 1: Create an embedded wallet
In this guide we’ll be using @turnkey/react-wallet-kit together with Auth Proxy.- Customize sub-organization creation process in your React application by defining the following TurnkeyProvider configuration. This will add a new Ethereum wallet account alongside the sub-organization creation.
proviers.tsx
- Handle authentication is using the
handleLogin
function from the useTurnkey hook. It’s idempotent — existing users simply log in to their sub-org.
page.tsx
Step 2: Create P-256 API key user
Next, use the authenticated end-user session to create a P-256 API key user whose key is managed by your backend for delegated actions. This will become the Delegated Access (DA) user once you define policies that grant it limited signing permissions. You can create this user at any point, either immediately after login or on-demand when an action (such as placing a limit order) requires delegated access. Note: This function is idempotent — calling it multiple times with the same publicKey will always return the same user rather than creating a new one.src/dashboard/page.tsx
- the user is not part of the root quorum, and
- no policy has been added yet to allow that action.
Step 3: Add a restrictive policy
Now that you’ve created the P-256 API key user, you can define policies that turn it into a Delegated Access (DA) user) — granting it limited permissions to sign specific transactions. In this example, we’ll allow the DA user to sign Ethereum transactions only to a given recipient address.src/dashboard/page.tsx
- Reminder, until this policy is added, the DA user cannot sign any transactions — it’s a non-root user with no permissions by default.
- The
fetchOrCreatePolicies
method compares the full intent signature of each policy you pass in:- If a policy already exists with the exact same fields, it will be reused.
- If any field differs, even something as small as the policy name or the notes text, it will be treated as a new policy and created again.