---
title: "Manage authentication | Grafana Loki documentation"
description: "Describes how to add authentication to Grafana Loki."
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# Manage authentication

Grafana Loki does not come with any included authentication layer. You must run an authenticating reverse proxy in front of your services.

The simple scalable and microservices [deployment modes](/docs/loki/next/get-started/deployment-modes/) require a reverse proxy to be deployed in front of Loki, to direct client API requests to the various components.

By default the Loki Helm chart includes a default reverse proxy configuration, using an nginx container to handle routing traffic and authorization.

A list of open-source reverse proxies you can use:

- [HAProxy](https://docs.haproxy.org/)
- [nginx](https://docs.nginx.com/nginx/) using their [guide on restricting access with HTTP basic authentication](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/)
- [OAuth2 proxy](https://oauth2-proxy.github.io/oauth2-proxy/)
- [Pomerium](https://www.pomerium.com/docs), which has a [guide for securing Grafana](https://www.pomerium.com/docs/guides/grafana)

> Note
> 
> Loki runs in multi-tenant mode by default (`auth_enabled: true`). In this mode, Loki requires the HTTP header `X-Scope-OrgID` to be set to a string identifying the tenant on every request; the responsibility of populating this value should be handled by the authenticating reverse proxy. A request that does not include this header fails with an HTTP `401 Unauthorized` error and the message `no org id`. To learn how to troubleshoot this error, refer to [No org ID](/docs/loki/next/operations/troubleshooting/troubleshoot-operations/#error-no-org-id). For more information, read the [multi-tenancy](/docs/loki/next/operations/multi-tenancy/) documentation.

For information on configuring authentication for your log shipping agent, see the [Grafana Alloy documentation](/docs/alloy/latest/).

## Mutual TLS

Loki’s HTTP and gRPC servers can require clients to present a valid TLS certificate before a connection is accepted. This is a form of client authentication that Loki supports natively, without a reverse proxy.

Mutual TLS (mTLS) authenticates the client at the transport level. It does not populate `X-Scope-OrgID`, so you still need a reverse proxy, your log shipping agent, or your client to set that header when `auth_enabled: true`.

To require client certificates, you must first enable TLS on the server by setting a certificate and a key, then set a client authentication policy and the certificate authority (CA) that signs your client certificates. For example:

YAML ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```yaml
server:
  http_tls_config:
    cert_file: /etc/loki/certs/server.crt
    key_file: /etc/loki/certs/server.key
    # Reject any client that does not present a certificate signed by this CA.
    client_auth_type: RequireAndVerifyClientCert
    client_ca_file: /etc/loki/certs/ca.crt
```

Use `client_ca_file` for the path to a CA certificate file, or `client_ca` to include the certificate contents directly in the configuration file. The `grpc_tls_config` block accepts the same options for the gRPC server. The equivalent command line flags are `-server.http-tls-client-auth` and `-server.http-tls-ca-path`, plus `-server.grpc-tls-client-auth` and `-server.grpc-tls-ca-path`.

The supported values for `client_auth_type` are:

- `NoClientCert`
- `RequestClientCert`
- `RequireAnyClientCert`
- `VerifyClientCertIfGiven`
- `RequireAndVerifyClientCert`

Use `RequireAndVerifyClientCert` for the strictest setting. It rejects a client that sends no certificate, and it also rejects a certificate that the CA did not sign. The other values check less. For example, `VerifyClientCertIfGiven` allows a client that sends no certificate at all. For the full list of TLS options, refer to the [server block](/docs/loki/next/configure/#server) of the configuration reference.

## Enable basic authentication for Loki using nginx

This section describes the process of enabling basic authentication for Loki using [nginx](https://docs.nginx.com/nginx/).

### Prerequisites

- A running Loki instance
- A running nginx instance

### Configure nginx

You must create a new nginx configuration file for the Loki instance.

This example assumes the following:

- nginx is running in `/opt/homebrew`
- Loki is running on port 3100 on the local machine
- Your Loki tenant id is `fake`
- The configuration file is named `/opt/homebrew/etc/nginx/loki.conf`

If you used different configuration parameters for Loki, adjust the examples to match your configuration.

`loki.conf` configuration:

conf ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```conf
upstream loki {
  server 127.0.0.1:3100;
  keepalive 15;
}

server {
  listen 80;
  server_name loki.localhost;

  auth_basic "loki auth";
  auth_basic_user_file /opt/homebrew/etc/nginx/passwords;

  location / {
    proxy_read_timeout 1800s;
    proxy_connect_timeout 1600s;
    proxy_pass http://loki;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Keep-Alive";
    proxy_set_header Proxy-Connection "Keep-Alive";
    proxy_redirect off;
  }

  location /ready {
    proxy_pass http://loki;
    proxy_http_version 1.1;
    proxy_set_header Connection "Keep-Alive";
    proxy_set_header Proxy-Connection "Keep-Alive";
    proxy_redirect off;
    auth_basic "off";
  }
}
```

> Tip
> 
> This example expects the client to send the `X-Scope-OrgID` header itself, in addition to the basic authentication credentials. If you run Loki with `auth_enabled: true`, you can instead have nginx set the tenant ID from the authenticated username. Add this line to the `location / {}` block:
> 
> conf ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy
> 
> ```conf
> proxy_set_header X-Scope-OrgID $remote_user;
> ```
> 
> With this line, nginx overwrites any tenant header sent by the client, so a client cannot read or write the data of another tenant. This requires each username in your password file to match a Loki tenant ID. The Loki Helm chart’s gateway uses this same pattern.

This configuration must be included in your main nginx configuration, for example, by including it in `nginx.conf` like:

YAML ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```yaml
include /opt/homebrew/etc/nginx/loki.conf;
```

Restart the nginx server to ensure all configuration changes are updated.

### Validate your nginx configuration

To validate the nginx configuration for Loki, you can send a `curl` request to two endpoints:

- The `/ready` endpoint, which is not protected by a basic authentication mechanism.

curl ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```curl
% curl -i http://loki.localhost/ready

HTTP/1.1 200 OK
Server: nginx/1.29.2
Date: Thu, 16 Oct 2025 14:28:31 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 6
Connection: keep-alive
X-Content-Type-Options: nosniff

ready
```

- The `/` endpoint, which is protected by a basic authentication mechanism.

curl ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```curl
curl -i http://loki.localhost/

HTTP/1.1 401 Unauthorized
Server: nginx/1.29.2
Date: Thu, 16 Oct 2025 14:32:43 GMT
Content-Type: text/html
Content-Length: 179
Connection: keep-alive
WWW-Authenticate: Basic realm="loki auth"

<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.29.2</center>
</body>
</html>
```

### Update passwords

The password file can be seeded using whatever mechanism you may use for other web services.

In this example, `htpasswd` is utilized:

![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```none
% htpasswd -c /opt/homebrew/etc/nginx/passwords loki123

New password:
Re-type new password:
Adding password for user loki123
```

Restart the nginx server to ensure all configuration changes are updated.

### Validate passwords

Enter your password into a temporary file, such as:

![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```none
% vi lokipw
```

Then, store it as an environment variable::

![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```none
% pass=$(cat lokipw)
```

You can validate basic authentication is then working by issuing a curl command to the protected resource:

curl ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```curl
curl -i -u loki123:$pass -H "X-Scope-OrgID:fake" "http://loki.localhost/loki/api/v1/labels"

HTTP/1.1 200 OK
Server: nginx/1.29.2
Date: Thu, 16 Oct 2025 14:46:09 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 21
Connection: keep-alive

{"status":"success"}
```
