# Step 3 - API Key Authentication

<QuickstartPicker
  mode="local"
  alternateLink="/articles/step-3-add-api-key-auth"
/>

In this guide we'll add API Key authentication to a route. You can do this for
any Zuplo project but will need a route, consider completing
[Step 1](./step-1-setup-basic-gateway-local.mdx) first.

API Key authentication is one of our most popular **policies** as implementing
this authentication method is considered one of the easiest to use by developers
but hard for API developers to get right. We also support JWT tokens and most
other authentication methods.

:::info{title="What's a Policy?"}

[Policies](./policies.mdx) are modules that can intercept and transform an
incoming request or outgoing response. Zuplo offers a wide range of policies
built-in (including API key authentication) to save you time. You can check out
[the full list](./policies.mdx).

:::

Let's get started.

<Stepper>

1.  Link your Local Project

    When developing locally with Zuplo, you can "link" your local project to
    your Zuplo project using the `zuplo link` command. This allows you to test
    your changes in a real environment.

    When you run the command you will be prompted to select your Zuplo account,
    project, and environment. You can pick any environment.

    ```bash
    npx zuplo link
    ```

    After your project is linked, environment variables and other configuration
    from your Zuplo project will be available in your local development
    environment.

1.  Start your Project

    You can start your project using the following command:

    ```bash
    npx zuplo dev
    ```

    After your project is started, you can open the local route designer at
    http://localhost:9100.

1.  Add the API Key Authentication Policy

    Open the local **Route Designer** by navigating to http://localhost:9100/.
    Select your route and click **Add Policy** on the incoming request policies
    section.

    <BrowserScreenshot url="http://localhost:9100/?path=routes.oas.json">

    ![Add Policy](../../public/media/step-3-add-api-key-auth-local/image.png)

    </BrowserScreenshot>

    Search for the API key authentication policy, click on it, and then click
    **Create Policy** to accept the default policy JSON.

    <ModalScreenshot>

    ![Add API Key Authentication](../../public/media/step-3-add-api-key-auth/choose-policy.png)

    </ModalScreenshot>

    :::tip

    The API key authentication policy should usually be one of the first
    policies executed. If you came here from
    [Step 2](./step-2-add-rate-limiting.mdx) then you will want to drag it above
    the rate limiting policy.

    :::

    ![reorder policies](../../public/media/step-3-add-api-key-auth/image-1.gif)

    If you test your route, you should get a 401 Unauthorized response

    ```json
    {
      "status": 401,
      "title": "Unauthorized",
      "type": "https://httpproblems.com/http-status/401"
    }
    ```

1.  Set up an API Key

    In order to call your API, you need to configure an API consumer. Go to the
    [Zuplo Portal](https://portal.zuplo.com), then open the project you are
    working on, **Services**, then click **Configure** on the "API Key Service".

    :::warning

    Be sure to select the appropriate environment in the dropdown on the top
    right of the services page. You must select the environment type you linked
    your local project to. If you only have a single environment, you should
    select "Production". Later we will create new environments for preview.

    :::

    ![API Key Service](../../public/media/step-3-add-api-key-auth/image-2.png)

    Then click **Create Consumer**.

    ![Create Consumer](../../public/media/step-2-add-api-key-auth/image-8.png)

    Let's break down the configuration needed.
    - Subject: Also known as `sub`. This is a unique identifier of the API
      consumer. This is commonly the name of the user or organization consuming
      your API
    - Key managers: The email addresses of those who will be managing this API
      key.
    - Metadata: JSON metadata that will be made available to the runtime when a
      key is used to authenticate. Common properties include the consumer's
      subscription plan, organization, etc.

    Go ahead and fill in `test-consumer` for the Subject. Add your own email as
    a Key manager, and leave the metadata empty for now. Click **Save consumer**
    once you're done.

    <ModalScreenshot>

    ![New Consumer](../../public/media/step-3-add-api-key-auth/image-3.png)

    </ModalScreenshot>

1.  Copy your API Key

    After your API Key consumer is created, copy your new API Key by clicking
    the copy button (next to the eye icon).

    ![Copy Key](../../public/media/step-3-add-api-key-auth/image-4.png)

1.  Test out your API Key

    Using any HTTP client (like Postman or curl), make a request to your API.

    ```bash
    curl --request GET \
    --url http://localhost:9000/path-1 \
    --header 'Authorization: Bearer zpka_d67b7e241bb948758f415b79aa8exxxx_2efbxxxx'
    ```

    You should get a 401 Unauthorized response - as we haven't supplied the API
    key yet. Add a new `authorization` header with the value
    `Bearer <YOUR_API_KEY>` and insert the API Key you got from the developer
    portal.

    You should now get a 200 OK.

    ```json
    {
      "url": "https://echo.zuplo.io/path-1",
      "method": "GET",
      "query": {},
      "headers": {
        "accept": "*/*",
        "accept-encoding": "gzip, br",
        "connection": "Keep-Alive",
        "host": "echo.zuplo.io",
        "true-client-ip": "12.63.237.42",
        "user-agent": "curl/8.7.1",
        "x-forwarded-proto": "https",
        "x-real-ip": "12.63.237.42",
        "zp-rid": "ecfac0de-f039-4ced-997c-b17c9babc944"
      }
    }
    ```

    :::note

    We also offer an API for our API key service that allows you to
    programmatically create consumers and even create your own developer portal
    or integrate key management into your existing dashboard. See
    [this document for details](./api-key-api.mdx).

    :::

</Stepper>

**NEXT** Try
[Step 4 - Connect Source Control and Deploy to the Edge](./step-4-deploying-to-the-edge.mdx).
