skip to content

You are connecting Grafana to a metrics and logs backend shared by several teams. What authentication options does a Grafana data source offer, how are its secrets stored, and what is the fundamental authorization gap you have to design around?

level: seniorimportance: must knowfreq 42%

answer

  1. basic / bearer / custom headers / mTLS / cloud signing / forwarded OAuth
  2. secure fields encrypted, write-only, never returned by the API
  3. query API takes a data-source UID, not a dashboard
  4. dashboard permissions ≠ data permissions
  5. per-tenant data source + permissions, or forward user identity

basics

~20 s

Options include basic auth, bearer tokens, custom headers (such as a tenant header), TLS client certificates, cloud-provider signing, and forwarding the user's OAuth identity. Secrets are stored encrypted server-side and never returned by the API. The gap: a data source is one shared identity, so dashboard permissions do not limit data access.

solid answer

~50 s

Per data source you typically get: no auth, **basic auth**, a **bearer token or custom HTTP headers** (how tenant headers such as a multi-tenant org header are set), **TLS** with a CA and optional client certificate, cloud-provider request signing, and **forwarding the signed-in user's OAuth token or identity** to the backend. Secrets are split: ordinary settings are stored in plain JSON and are readable through the API; sensitive fields are stored **encrypted** with the instance secret key (optionally wrapped by an external KMS) and are **write-only** — the API returns a "configured" marker, never the value. The gap is structural: a data source is a **single shared identity**. Queries are addressed by data-source UID, so anyone permitted to use that data source can issue *any* query it can serve, regardless of which dashboards they can see. Dashboard permissions are navigation, not data authorization. Designs that close it: one data source per tenant, restricted by data-source permissions; or forward the user's identity so the backend authorizes per user.

go deeper

for a junior

List the auth options and know that secrets are stored encrypted on the server and cannot be read back through the UI or API.

for a middle

Explain the jsonData/secureJsonData split, custom headers as tenant selectors, and that the query API is addressed by data source rather than by dashboard.

for a senior

Lead with the authorization gap and present the two real designs — per-tenant data sources with restricted use, or forwarded user identity — with their costs, including the headless-evaluation problem.

for a principal

Treat Grafana as a credential concentrator and set the trust boundary deliberately: which system authorizes, how tenants are isolated, how keys are wrapped and rotated, and what the blast radius is if the Grafana database leaks.

## The authentication surface A Grafana data source's configuration form is, for HTTP-based backends, a fairly uniform set of options: - **No auth** — appropriate only inside a trusted network boundary, and even then it means anything that can reach the backend can read everything. - **Basic auth** — username and password, injected server-side. - **Bearer token / Authorization header** — via the custom HTTP headers mechanism, which lets you add arbitrary header name/value pairs where the value is stored as a secret. - **Custom headers as tenant selectors** — the same mechanism carries a tenancy header (for example the org/tenant header used by multi-tenant metric and log backends), which is how one backend serves many isolated tenants. - **TLS options** — a CA certificate to trust a private authority, a client certificate and key for mutual TLS, a server-name override, and a "skip verify" switch that should be treated as a defect in production. - **Cloud-provider auth** — request signing with access keys or an assumed role, or managed workload identity, depending on the provider plugin. - **Forwarded user identity** — an option to attach the signed-in user's OAuth access token (or an identity assertion) to the outgoing request, so the backend sees *the user*, not Grafana. - **Timeouts, connection limits and proxy settings** — unglamorous but load-bearing, since a data source with no timeout turns a slow backend into a hung Grafana. ## How secrets are stored Grafana splits a data-source configuration into two buckets. Non-sensitive settings live as plain JSON in Grafana's database and are returned by the configuration API — anyone with configuration read access sees them. Sensitive fields live in a separate encrypted bucket, encrypted with the instance's secret key; deployments can wrap that key with an external key-management service so the database alone is not enough to decrypt. The important behavioural detail is that secure fields are **write-only through the API and UI**: once saved, the value is never returned, and the form shows a "configured" state with a reset control. This is why you cannot recover a lost password from Grafana, why an export of a data source is not a credential leak, and why automated configuration must supply the secret from its own source of truth every time rather than reading it back. Rotating the instance secret key requires re-encrypting stored secrets, which is a planned operation, not an emergency one — worth knowing before an incident forces it. ## The authorization gap This is the part that separates a senior answer. Grafana's query API takes a **data-source UID** and a query. It does not take a dashboard. So the ability to see a dashboard and the ability to query its data are different things: - A user who can reach a data source can craft arbitrary queries against it — via an ad-hoc exploration view, via editing a panel, or by calling the API directly — and see everything that data source's single identity can see. - Hiding a dashboard, hiding a panel, filtering rows in a transformation, or restricting a folder does **not** restrict data. Those are navigation and presentation. - Consequently, if one data source can read every team's metrics, every Grafana user who can use it can read every team's metrics. ## Designs that actually enforce isolation 1. **One data source per tenant, plus data-source permissions.** Create a data source per team whose configuration pins that team's tenant (typically via the tenancy header or a scoped token), then restrict who may use each one. This puts enforcement in two places — the backend honours the tenant header, and Grafana restricts who can address that UID. Fine-grained data-source permissions are an Enterprise/Cloud capability; on open-source Grafana the equivalent is separate organisations or separate Grafana instances. 2. **Forward the user's identity.** Enable OAuth identity forwarding (or an equivalent per-user token) so the backend authorizes each query against the requesting human. This is the only design where Grafana is not the trust boundary — the backend is — and it is the right answer whenever the backend already has per-user authorization. Its costs: the backend must accept and validate those tokens, token lifetime and refresh become part of the query path, and anything evaluated *without* a user — alert rules, scheduled reports, caching — has no user token and therefore needs a separate service identity anyway. 3. **Separate Grafana organisations or instances per tenant.** Coarse, operationally heavier, but unambiguous — and the standard fallback where fine-grained permissions are unavailable. ## Practical checks worth naming - "Save & test" verifies reachability and that the credentials authenticate. It proves nothing about what rows or series the identity may read, and nothing about tenancy. - Grant the data source's identity the least privilege it needs: read-only, scoped to the intended tenant or database, never an administrative account. - Treat TLS skip-verify as an outage waiting to become a compromise; fix trust instead by supplying the CA. - Grafana holds many credentials in one place, which makes it a high-value target: protect its admin roles and its configuration API as carefully as you protect the backends themselves.

  • A viewer can only open one dashboard, which shows a single team's metrics. Can they see other teams' metrics?
    Yes, if the panel's data source is a shared one they are permitted to use. The query API is addressed by data-source UID, so they can query it directly — through an exploration view, by editing a panel, or via the HTTP API — and retrieve anything that data source's identity can read. Restricting the dashboard restricts navigation, not data; enforcement has to be per data source or per user at the backend.
  • You enable OAuth identity forwarding so the backend authorizes each user. What still needs a service identity, and why?
    Anything evaluated without a signed-in user: alert-rule evaluation, scheduled reports, recorded queries and cache warming all run on the server's schedule with no user token available. Those paths need their own credential, which means you must decide what that service identity is allowed to see — and accept that an alert rule may legitimately evaluate over data an individual user could not query.
  • Someone asks you to enable TLS skip-verify to get a data source working quickly. What do you say?
    It disables certificate verification, so the connection is encrypted but unauthenticated and any party able to intercept the route can impersonate the backend and receive the credentials Grafana sends. The correct fix is to supply the private CA certificate in the data source's TLS settings, or to correct the server name so the presented certificate validates. Treat skip-verify as a temporary diagnostic, never a saved configuration.

saying these in an interview costs you the question

  • Claiming dashboard or folder permissions restrict what data a user can query
  • Assuming a secret can be read back from the Grafana API for reuse elsewhere
  • Enabling TLS skip-verify and calling the connection secure
  • Giving the data source an administrative account because a read-only one was 'inconvenient'
  • Believing forwarded user identity solves authorization for alert rules, which run without a user

context