# Disabled authentication

ODD Platform allows to disable authentication at all. This is useful when you want to deploy platform locally and don't need any security configured. This is the default configuration and no additional settings are required.

{% tabs %}
{% tab title="YAML" %}

```yaml
auth:
    type: DISABLED
```

{% endtab %}

{% tab title="Environment variables" %}

```
AUTH_TYPE=DISABLED
```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
**DO NOT** use this method in your production environment!
{% endhint %}

The rest of this page enumerates what an anonymous caller on the network can reach under `auth.type: DISABLED`. The intent is not to soften the warning above — it is to give operators the specific surface area so they understand the warning's scope.

## What's anonymously reachable

The DISABLED-mode security configuration accepts every exchange (`.anyExchange().permitAll()`) — every HTTP endpoint on the platform is reachable to an unauthenticated caller. The surfaces below are the load-bearing ones an operator should know about before exposing a DISABLED-mode deployment on any network broader than `localhost`:

* **`GET /api/identity/whoami`** returns a synthetic admin identity: `{ "username": "admin", "permissions": [ … every Permission value defined on the platform … ] }`. The permission set is built from `Permission.values()`, so any new platform capability added in a future release is **automatically** granted to this anonymous synthetic admin — there is no per-permission opt-in. Every UI control gated by a permission unlocks; every state-changing endpoint accepts mutations from any caller on the network.
* **`GET /api/appInfo`** returns the precise platform version (`buildProperties.getVersion()`) and the active `auth.type` value, with no authentication. The `authType` field shape is ODD-specific — a passive network scanner can confirm the deployment IS ODD Platform, learn its version (CVE-scoping), and learn the auth-mode value in one unauthenticated `GET`.
* **`GET /actuator/env`** returns the **schema** of configured properties — which OAuth2 providers are wired (the property-key prefixes), whether LDAP is configured, that a JDBC datasource is configured (the `spring.datasource.url` key, not its value). The actuator namespace `/actuator/**` is whitelisted in Spring Security in every auth mode (not just DISABLED), and the default `management.endpoints.web.exposure.include` setting includes `env`. Property *values* are masked (`******`) for every caller by default (`show-values` defaults to `NEVER`), but the property **keys and sources** are still informative for an attacker mapping the deployment.
* **Every `/api/**` endpoint** is reachable as a mutation surface. Owner CRUD, Policy / Role / Permission mutations, Lookup-table data row mutations, attachment uploads, custom-metadata writes, business-glossary term writes — every state-changing endpoint accepts requests with no auth. The platform's data integrity under DISABLED depends entirely on operator-side network isolation.

## Fingerprint matrix (passive recon)

An unauthenticated caller can determine the platform's auth mode in **one** request by observing the response shape of `GET /api/identity/whoami`. The four mode-distinguishing responses:

| `auth.type`       | Response to anonymous `GET /api/identity/whoami`             | What it tells the caller                          |
| ----------------- | ------------------------------------------------------------ | ------------------------------------------------- |
| `DISABLED`        | `200 OK` + `{ "username": "admin", "permissions": [ ... ] }` | Mode known; full admin reach to anonymous caller. |
| `LOGIN_FORM`      | `302 Found` → `/login`                                       | Mode known; credentials gating exists.            |
| `OAUTH2` / `LDAP` | `401 Unauthorized`                                           | Mode known; OIDC / LDAP auth required.            |

DISABLED is the easiest mode to fingerprint anonymously on the network. The combination with `GET /api/appInfo` (which surfaces the auth-mode value directly) means an anonymous network scan can confirm-ODD + version + auth-mode + reach the admin endpoint in a handful of unauthenticated requests.

## Reserved usernames

The DISABLED-mode synthetic identity uses the literal lowercase string `admin`; the S2S authentication filter uses the literal uppercase string `ADMIN`. The platform's user-to-owner mapping table compares names case-sensitively. Avoid provisioning operator-managed users with either of these literal names in `LOGIN_FORM`, `LDAP`, or any OAuth2 provider — a user named `admin` or `ADMIN` collides with the synthetic identities and inherits whatever owner mapping the synthetic principal resolves to. See the matching note on the [Server-to-server (S2S) authentication](/configuration-and-deployment/enable-security/authentication/s2s.md#operator-caveats) page.

## Migrating away from DISABLED

When you flip `auth.type` from `DISABLED` to `LOGIN_FORM`, `OAUTH2`, or `LDAP`, the synthetic-admin response from `GET /api/identity/whoami` vanishes — anonymous callers stop seeing the admin grant. For the cross-mode comparison of how each target mode grants ADMIN, see [Admin promotion across providers](/configuration-and-deployment/enable-security/admin-promotion.md). **Before flipping**, audit:

* Any existing `Owner` rows whose `OIDC_USERNAME` matches the literal `admin` or `ADMIN` — these will collide with the DISABLED synthetic identity (or with S2S — see [S2S](/configuration-and-deployment/enable-security/authentication/s2s.md)) once the platform starts attributing real user names through the real auth chain.
* Any RBAC `Policy` or `Role` you authored while running DISABLED — they were never consulted under DISABLED (every caller was admin), so they take effect for the first time when the migration completes; mis-configurations that were silent under DISABLED start to bite immediately.
* Network exposure that you tolerated under DISABLED on the assumption that the deployment was only-on-localhost — verify that the network boundary is still where you think it is before the synthetic admin disappears.


---

# 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.opendatadiscovery.org/configuration-and-deployment/enable-security/authentication/disabled-authentication.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.
