# Authenticated Requests

To carry out an unauthenticated request, 4 headers are required:

1. Authentication Header - `X-Encrypted-Session or`` ``X-Encrypted-WebAuthn-Signature or`` ``X-Encrypted-Key-Signature`
2. `X-Encrypted-Key`
3. `X-Encrypted-User`&#x20;
4. `X-Scope-Id`&#x20;

`X-Encrypted-Session` is obtained when you authenticate with the [Authenticating with API](/authentication/passkeys/authentication/authenticating-with-api.md) endpoint. This is used by enclave to verify  your requests. Other 2 types of headers are obtained by signing the user details object directly using your auth method (passkeys or private key)

To setup an `X-Encrypted-Key` you need to generate a random AES Key, and then RSA encrypt it with the secure enclaves public key, we'll use TypeScript for the example below.

Here we setup a `cryptoObj` that can work in both browser and server environments and then a function to generate an AES Key.

```javascript
const cryptoObj = typeof window !== "undefined" ? window.crypto : crypto;

export const generateAesKey = async () => {
  const cryptoKey = await cryptoObj.subtle.generateKey(
    {
      name: "AES-GCM",
      length: 256,
    },
    true,
    ["encrypt", "decrypt"]
  );
  return await cryptoObj.subtle.exportKey("raw", cryptoKey);
};
```

Next we setup two function an `encrypt` function, which we then use in our `rsaEncrypt` function.

```typescript
const encrypt = async (algo, key, data) => {
  try {
    const encryptedResult = await cryptoObj.subtle.encrypt(algo, key, data);
    return encryptedResult;
  } catch (error) {
    console.error("Encryption error:", error);
    throw error;
  }
};

const rsaEncrypt = async (
  plainText: string,
  encryptionKey: BufferSource,
  keyFormat: "spki" = "spki",
  hashName: "SHA-256" = "SHA-256"
) => {
  if (!encryptionKey) {
    throw Error("Encryption key not initialized");
  }

  const encoder = new TextEncoder();
  const data = encoder.encode(plainText);

  let cryptoKey: CryptoKey;
  let encrypted: ArrayBuffer;

  try {
    cryptoKey = await importKey(
      keyFormat,
      encryptionKey,
      { name: "RSA-OAEP", hash: { name: hashName } },
      ["encrypt"]
    );
    encrypted = await encrypt({ name: "RSA-OAEP" }, cryptoKey, data);
    return btoa(String.fromCharCode.apply(null, new Uint8Array(encrypted)));
  } catch (error) {
    console.error("RSA-OAEP Encryption error:", error);
    throw error;
  }
};


export const aesEncrypt = async (
  plainText: string,
  encryptionKey: BufferSource,
  keyFormat: "raw" = "raw",
  keyLength: number = 256
) => {
  if (!encryptionKey) {
    throw Error("Encryption key not initialized");
  }

  const encoder = new TextEncoder();
  const data = encoder.encode(plainText);
  let cryptoKey: CryptoKey;
  let encrypted: ArrayBuffer;

  try {
    cryptoKey = await importKey(keyFormat, encryptionKey, { name: "AES-GCM", length: keyLength }, [
      "encrypt",
    ]);

    const iv = cryptoObj.getRandomValues(new Uint8Array(12)); // Initialization vector

    encrypted = await encrypt({ name: "AES-GCM", iv }, cryptoKey, data);

    const combined = new Uint8Array(iv.length + encrypted.byteLength);
    combined.set(iv, 0);
    combined.set(new Uint8Array(encrypted), iv.length);

    return btoa(String.fromCharCode.apply(null, combined));
  } catch (error) {
    console.error("AES-GCM Encryption error:", error);
    throw error;
  }
};

```

&#x20;With these function setup, we are able to generate our AES key, and then RSA Encrypt it using the public key of the secure enclave.&#x20;

```typescript
const enclavePublicKey = 
  "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvQOa1gkatuN6KjaS4KEWsVZAN9i4Cf0j9jlmBW5RwCJ3Bxo32McP7axt4Ev6sMWM24lpCgXgu68S9KBYRcrcEB6dRcaupFGd+ER7M518fiJ0VtCZ+XRnmwn9fqEvotp9DPZOysJkUQ60kugCRKwNvfZzAFcDiubwiqsUY2sCm943a/u9Hym51SEetG+ZFPJZFOBqwRSGkOgGZ+9Ac7ITE+bWLCZk9DlzRu+BIoDOFzXZIn+/0a0X8BnLtRY4g50aew4J+4OllQagBbhYnPMvYExYIEUx6bdjQicw0Js6s2pHr+SFAX23kQtbVOVxb5+KEGp1d+6Q4Gx7FBoyWI5qPQIDAQAB";

const aesKey = await generateAesKey();
const aesKeyBytes = new Uint8Array(aesKey);
const aesKeyString = btoa(String.fromCharCode(...aesKeyBytes));
const encryptedAesKey = await rsaEncrypt(aesKeyString, enclavePublicKey);
const userDetails = {
    username: "john_doe",
    userDisplayName: "john_doe_crypto",
};
const encryptedUser = await aesEncrypt(JSON.stringify(userDetails), aesKey);
```

Now you have your `encryptedAesKey` and `encryptedUser` you can use this value as the value in the request header as `X-Encrypted-Key` . With `X-Scope-Id, X-Encrypted-User` , X-Encrypted-Session and `X-Encrypted-Key` setup, you can now start interacting with Passport API to sign messages, transactions and everythig else!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.0xpass.io/appendix/api-request-setup/authenticated-requests.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
