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

# Security

> How the Nmbr Component secures communication between your app, your server, and the Nmbr API.

The Nmbr Component is designed so that your API secret is never exposed to the browser. Every API call made by the component is authenticated using a JWT signature produced by your server, ensuring that only authorized requests reach the Nmbr API.

## How Request Signing Works

When the Nmbr Component needs to interact with the Nmbr API (for example, to load payroll data or submit changes), it does not call the API directly. Instead, it follows a three-step signing flow:

### 1. The Component Intercepts the Request

Before any API call leaves the browser, the Nmbr Component intercepts it and extracts the request body. This body contains the data that will be sent to the Nmbr API.

### 2. Your Server Signs the Request

The component sends the request body to the **signing endpoint** you configured during [initialization](/components/getting-started#initialize-nmbr-components) (via `signingUrl` or a custom `sign` function). Your server:

1. Receives the JSON request body
2. Signs the body as a JWT using the **SHA-256 hash** of your API Secret and the **HS256** algorithm
3. Returns the signed JWT token to the component

Because this step happens on your server, your API Secret is never sent to or accessible from the browser.

### 3. The Component Calls the Nmbr API

The component takes the signed JWT returned by your server and includes it with the API request to the Nmbr API. The Nmbr API validates the signature to confirm the request was authorized by your server before processing it.

<img src="https://mintcdn.com/nmbr/d7Nj4IbcnnG3-_f8/assets/component.security.flow.png?fit=max&auto=format&n=d7Nj4IbcnnG3-_f8&q=85&s=d63a57b44f41b7395dbffa8e5524d628" alt="Diagram showing the request signing flow between the browser, your server, and the Nmbr API" width="511" height="273" data-path="assets/component.security.flow.png" />

## Why This Architecture?

### API Secret Never Leaves Your Server

The signing flow ensures that your API Secret is only ever used server-side. The browser never has access to it, which eliminates the risk of credential exposure through client-side code, browser extensions, or network inspection.

### You Control Authorization

Your signing endpoint is a server-side route in your application. This means you can enforce your own authentication and authorization logic before signing any request. For example, you can verify that the current user is logged in and has permission to administer payroll before returning a signature.

### Every Request is Verified

The Nmbr API validates the JWT signature on every incoming request. If a request has been tampered with or was not signed by your server, it will be rejected.

## Signing Endpoint Requirements

Your signing endpoint must:

* Accept `POST` requests with a JSON body
* Sign the body as a JWT using the **HS256** algorithm
* Use the **SHA-256 hash** of your API Secret as the signing key (hex-encoded or base64-encoded)
* Return the signed JWT as plain text with a `201` status code
* Be protected by your own authentication and authorization. See [Authenticating the Signing Request](#authenticating-the-signing-request) below

For implementation examples in Ruby, Node.js, PHP, and .NET, see the [Getting Started guide](/components/getting-started#create-a-signing-endpoint).

## The Signed Payload

The Component builds the JWT payload for each API request. Your `signingUrl` or `sign` function should sign the JSON it receives as-is. You do not need to create or change the JWT claims.

If you inspect or build the payload yourself, set the `uri` claim to the API request path, including the query string when one is present. Exclude the scheme, host, and `/services/payroll` base path.

For example:

* `GET https://sandbox.nmbr.co/services/payroll/employees?per_page=5` → `uri: "/employees?per_page=5"`
* `GET https://sandbox.nmbr.co/services/payroll/employees` → `uri: "/employees"`

## Authenticating the Signing Request

Note: cookies are not sent to your signing endpoint by default. The following approaches are supported:

### Bearer Authentication

Send a token in an HTTP header on every signing request and validate it server-side. The token can be an API key, signed token, or bearer JWT from your own auth system. Use the [custom `sign` function](#custom-signing-function) below to attach the header. `signingUrl` does not support custom headers.

### Cookie Authentication

If your architecture specifically requires cookie-based auth, the [custom `sign` function](#custom-signing-function) below lets you write your own `fetch` call with `credentials: 'include'`.

## Custom Signing Function

If your application architecture requires more control over the signing process (for example, if you need to add custom headers or use a different transport), you can provide a `sign` function instead of a `signingUrl` when initializing the component:

```typescript theme={null}
window.components = nmbr.initialize({
  companyId,
  partnerId,
  sign: async (json: string): Promise<string> => {
    const response = await fetch('/your-custom-endpoint', {
      method: 'POST',
      headers: {
        Accept: 'text/plain',
        'Content-Type': 'application/json',
        Authorization: `Bearer ${yourSessionToken}`,
      },
      body: json,
    });

    return response.text();
  },
});
```

This gives you full control over how the signing request is made while maintaining the same security guarantees.

## Best Practices

* **Protect your signing endpoint** — Ensure it is behind authentication so that only logged-in users with the appropriate permissions can request signatures.
* **Store your API Secret securely** — Use environment variables or a secrets manager. Never hard-code it in source files or commit it to version control.
* **Use HTTPS** — All communication between the browser, your server, and the Nmbr API should be over HTTPS to prevent interception.
* **Limit access** — Only users who need to administer payroll should be able to reach the signing endpoint.
