> ## Documentation Index
> Fetch the complete documentation index at: https://developers.squads.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Authorization

> Understanding how to authorize intents in Grid

Authorization in Grid follows the principles of Open Banking, where actions require explicit authorization from the appropriate authorities. This is implemented through blockchain signatures, making it secure and verifiable.

<Info>
  The technical implementation details shown below will be abstracted away in an
  upcoming Grid SDK. The SDK will handle all the complexity of authorization,
  key management, and Turnkey integration, making it much easier to implement
  Grid's authorization system in your applications.
</Info>

## How Authorization Works

Grid uses a two-step authorization process:

1. Email-based authentication that provides a credential bundle valid for a specified duration (defaults to 1 hour)
2. Authority-based signing of intents using the credential bundle

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant Grid
    participant Authority
    participant Ledger (Solana)

    Note over Client,Grid: One-time setup (valid for specified duration)
    Client->>Grid: POST /auth
    Note over Client,Grid: Request OTP (expires in 1 hour by default)
    Grid-->>Client: Return OTP ID

    Client->>Grid: POST /verify-otp
    Note over Client,Grid: Verify OTP
    Grid-->>Client: Return credential bundle

    Note over Client,Grid: Reuse credential bundle until expiration
    loop Intent Creation & Authorization
        Client->>Grid: POST /payment-intents
        Note over Client,Grid: Create payment intent
        Grid-->>Client: Return intent details

        Client->>Authority: Request authorization
        Note over Client,Authority: Entity approves intent
        Authority-->>Client: Return authorized intent

        Client->>Grid: POST /payment-intents/{id}/confirm
        Note over Client,Grid: Submit authorized intent
        Grid->>Ledger (Solana): Execute transaction
        Grid-->>Client: Confirm execution
    end

    Note over Client,Grid: After expiration, repeat auth flow
```

### Authority Types

Grid supports various types of authorities, each with specific permissions that determine what actions they can perform:

* `CAN_INITIATE`: Authorities that can create new intents
* `CAN_VOTE`: Authorities that can approve intents
* `CAN_EXECUTE`: Authorities that can execute approved intents

Each authority must have a Solana-compatible Secp256k1 keypair, which is used to sign transactions and verify ownership of the authority.

### Creating and Managing Authorities

Grid provides two ways to create authorities, with email-based creation being the recommended default approach for most use cases:

1. **Email-based Authority Creation (Recommended)**: The simplest way to create authorities using Grid's built-in authentication:

   * Authenticate using the `/auth` endpoint to receive an OTP
   * Verify the OTP using the `/verify-otp` endpoint
   * Grid automatically generates and manages a Solana-compatible keypair for the authority
   * The verified authority can then be used to authorize intents

2. **External Authority Creation**: For advanced use cases, you can create authorities externally:
   * Generate a Solana-compatible Secp256k1 keypair
   * Submit the public key to Grid when creating a smart account
   * Define the authority's permissions in the smart account's policies
   * Manage the private key securely in your own infrastructure

### Technical Implementation

The email-based authentication process uses Turnkey's API key stamper for secure key management. Here's how it works:

<Info>
  For more details on Turnkey's API key stamper implementation, see the [Turnkey
  API Documentation](https://docs.turnkey.com/sdks/advanced/api-key-stamper).
</Info>

```typescript theme={null}
import { decryptCredentialBundle } from "@turnkey/crypto";
import { signWithApiKey } from "@turnkey/api-key-stamper";
import { getPublicKey } from "@turnkey/crypto";
import {
  stringToBase64urlString,
  uint8ArrayFromHexString,
  uint8ArrayToHexString,
} from "@turnkey/encoding";

// Decrypt the credential bundle received from OTP verification
const decryptedData = decryptCredentialBundle(
  credentialsBundle,
  keypair.privateKey
);

// Get the public key from the decrypted data
const publicKey = uint8ArrayToHexString(
  getPublicKey(uint8ArrayFromHexString(decryptedData), true)
);

// Prepare the input for signing
const input = {
  subOrganizationId: accountInfo.mpc_primary_id,
  email: email,
  publicKey: keypair.publicKey,
};

// Sign the input using Turnkey's API key stamper
const signature = await signWithApiKey({
  content: input,
  publicKey,
  privateKey,
});

// Create the final stamp for authorization
const stamp = {
  publicKey,
  scheme: "SIGNATURE_SCHEME_TK_API_P256",
  signature,
};
```

This implementation ensures secure key management and proper authorization of intents through Turnkey's infrastructure.

## Example: Authentication and OTP Verification

<Steps>
  <Step title="Authenticate and get OTP">
    Send a POST request to authenticate and receive an OTP:

    ```bash theme={null}
    curl -X POST https://grid.squads.xyz/api/v0/grid/smart-accounts/auth \
      -H "Content-Type: application/json" \
      -H "x-grid-environment: sandbox" \
      -d '{
        "email": "user@example.com",
        "app_name": "My App",
        "app_icon_url": "https://example.com/icon.png",
        "expiration": 3600
      }'
    ```

    The response will contain an OTP ID and MPC primary ID:

    ```json theme={null}
    {
      "data": {
        "otp_id": "otp_123",
        "mpc_primary_id": "mpc_456"
      }
    }
    ```
  </Step>

  <Step title="Verify OTP and get credential bundle">
    Use the OTP to verify and receive a credential bundle:

    ```bash theme={null}
    curl -X POST https://grid.squads.xyz/api/v0/grid/smart-accounts/verify-otp \
      -H "Content-Type: application/json" \
      -H "x-grid-environment: sandbox" \
      -d '{
        "mpc_primary_id": "mpc_456",
        "otp_id": "otp_123",
        "otp_code": "123456",
        "auth_public_key": "0x...",
        "expiration": 3600
      }'
    ```

    The response includes the credential bundle and account information:

    ```json theme={null}
    {
      "data": {
        "credential_bundle": "cred_789",
        "account_info": {
          "mpc_primary_id": "mpc_456",
          "smart_account_signer_public_key": "0x...",
          "wallet_id": "wallet_123",
          "smart_account_address": "0x...",
          "grid_user_id": "user_456"
        }
      }
    }
    ```
  </Step>
</Steps>

The credential bundle obtained from this process can then be used to authorize intents and transactions on behalf of the smart account.

## API Reference

For detailed API specifications, see the [Authorization API Reference](/grid/v0/api-reference/endpoint/core/authenticate-email-authority).
