## 1. Project Overview & Quickstart (rommapp/authelia)

# authelia

The Single Sign-On Multi-Factor portal for web apps, now OpenID Certified™

### Repository Details
- **Repository:** [rommapp/authelia](https://github.com/rommapp/authelia)
- **GitHub Stars:** ⭐ 28,547
- **Primary Language:** Go

*Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.*

## 2. Official Technical Reference & Guides (rommapp/docs)

## File: README.md

# Overview

This is the [official documentation](https://docs.romm.app) repository of [RomM](https://romm.app/), the beautiful, powerful self-hosted ROM manager and player.

# Contributing

To contribute to RomM's documentation, please check [Contribution Guide](CONTRIBUTING.md).

# Community

Join us on Discord, where you can ask questions, submit ideas, get help, showcase your collection, and discuss RomM with other users.

[![discord-invite]][discord-invite-url]



[license-badge-img]: https://img.shields.io/github/license/rommapp/docs?style=for-the-badge&color=a32d2a
[license-badge]: LICENSE
[discord-badge-img]: https://img.shields.io/badge/discord-7289da?style=for-the-badge
[discord-badge]: https://discord.gg/P5HtHnhUDH



[discord-invite]: https://invidget.switchblade.xyz/P5HtHnhUDH
[discord-invite-url]: https://discord.gg/P5HtHnhUDH

---

## File: docs/about/brand-guidelines.md

---
title: Brand Guidelines
---



# Brand Guidelines

In this context, "RomM", "The RomM Project", "the project", "we", "us", and "our" refer to the RomM project and organization.

## The logo



The logo should always be used in its standard colors:





## Do these things

- Use our logo to link to any page or site operated by the project.
- Use our logo in a blog post or news article about the project.
- Use our logo to inform others that your project integrates with RomM.
- Always use our logo in the colors provided.
- Always use our name in a way that makes clear you are not affiliated with the project.

If you're building something that integrates with RomM and would like to use/remix the logo, **please reach out first** via [Discord](https://discord.gg/romm). We'd love to hear about it.

## Please don't

- Use our name or logo in any way that suggests you are us, are endorsed by us, or are part of the project.
- Use our name or logo in a way that implies partnership, sponsorship, or endorsement.
- Use our name or logo as the name or logo for your project, product, service, social media account, company, or website.
- Use our name or logo to promote, advertise, or sell any private business, closed-source software, commercial product, or paid service.

## Downloadables

The logo assets live at [rommapp/romm/tree/master/frontend/assets/](https://github.com/rommapp/romm/tree/master/frontend/assets/):

- `isotipo.svg`/`isotipo.png`: the mark (circular logo)
- `logotipo.svg`/`logotipo.png`: the wordmark
- `social_preview.png`: GitHub social preview

## Questions

Ask on [Discord](https://discord.gg/romm) or open an issue.

---

## File: docs/about/credits.md

---
title: Credits
---

# Credits

This project exists because a lot of people contributed code, designs, translations, ideas, and, most importantly, running bug reports back to the project. Thanks to every one of them.

## Contributors

[Every contributor](https://github.com/rommapp/romm/graphs/contributors) to [rommapp/romm](https://github.com/rommapp/romm), plus contributors to the surrounding repos:

- [rommapp/argosy-launcher](https://github.com/rommapp/argosy-launcher/graphs/contributors)
- [rommapp/grout](https://github.com/rommapp/grout/graphs/contributors)
- [rommapp/playnite-plugin](https://github.com/rommapp/playnite-plugin/graphs/contributors)
- [rommapp/docs](https://github.com/rommapp/docs/graphs/contributors)

## Translators

The 19 locales exist because individual community members took the time to translate the UI. See each locale folder's commit history at [rommapp/romm/tree/master/frontend/src/locales](https://github.com/rommapp/romm/tree/master/frontend/src/locales) for per-locale credit.

## Community apps

Built by the community, not the RomM team. Full list in the [Community section in the RomM README](https://github.com/rommapp/romm/#community).

## Financial supporters

Donors via [Open Collective](https://opencollective.com/romm) make continued development possible. The project wouldn't exist without you. Thank you! ❤️

## Upstream projects

This stack stands on an enormous amount of open-source work. In rough order of "how visible they are to users":

### In-browser emulation

- [EmulatorJS](https://emulatorjs.org/)
- [Ruffle](https://ruffle.rs/)
- [dosbox-pure](https://github.com/schellingb/dosbox-pure)

### Metadata sources

- [IGDB](https://www.igdb.com/)
- [ScreenScraper](https://screenscraper.fr/)
- [MobyGames](https://www.mobygames.com/)
- [RetroAchievements](https://retroachievements.org/)
- [SteamGridDB](https://www.steamgriddb.com/)
- [Hasheous](https://hasheous.org/)
- [Playmatch](https://github.com/RetroRealm/playmatch)
- [LaunchBox Games Database](https://gamesdb.launchbox-app.com/)
- [TheGamesDB](https://thegamesdb.net/)
- [Flashpoint Archive](https://flashpointproject.github.io/flashpoint-database/)
- [HowLongToBeat](https://howlongtobeat.com/)
- [Libretro](https://www.libretro.com/)

### Backend stack

- [FastAPI](https://fastapi.tiangolo.com/) + [Starlette](https://www.starlette.io/)
- [SQLAlchemy](https://www.sqlalchemy.org/) + [Alembic](https://alembic.sqlalchemy.org/)
- [RQ](https://python-rq.org/)
- [MariaDB](https://mariadb.org/)/[PostgreSQL](https://www.postgresql.org/)/[MySQL](https://www.mysql.com/)
- [Redis](https://redis.io/)/[Valkey](https://valkey.io/)
- [nginx](https://nginx.org/) with [`mod_zip`](https://github.com/evanmiller/mod_zip)
- [uv](https://docs.astral.sh/uv/)

### Frontend stack

- [Vue 3](https://vuejs.org/)
- [Vuetify](https://vuetifyjs.com/)
- [Pinia](https://pinia.vuejs.org/)
- [Vite](https://vitejs.dev/)
- [socket.io](https://socket.io/)
- [vue-i18n](https://vue-i18n.intlify.dev/)
- [rom-patcher-js](https://www.marcrobledo.com/RomPatcher.js/)
- [vite-plugin-pwa](https://vite-pwa-org.netlify.app/)

### Docs stack

- [MkDocs](https://www.mkdocs.org/) + [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/)
- [mike](https://github.com/jimporter/mike) for docs versioning
- [asciinema](https://asciinema.org/) for terminal recordings

## Missing?

Open a PR against this page. Credit is cheap, and we want to give it where it's due.

## See also

- [License](license.md)
- [Contributing](../developers/contributing.md)

---

## File: docs/about/faqs.md

---
title: FAQs
---

# FAQs

## What is RomM?

RomM (ROM Manager) allows you to scan your library, pull metadata, browse a clean UI, play in the browser, sync to handhelds, and run it all on your own hardware.


!!! note "RomM is server software you run on a homelab box or NAS"
    It is not a desktop app, and there's no `.exe` or `.appimage`. You'll need basic Linux + Docker skills to set it up. **Games and copyrighted material aren't provided.**

## Is it free?

Yes! Licensed under [AGPL-3.0](license.md), the core will always be free. Other repos under our umbrella use equally permissive licenses, and there's no tracking or upsells.

## How does it compare to [X other manager]?

The emphasis here is self-hosted + multi-user + in-browser-play + the companion-app ecosystem. If those matter, try it, but if you just want a local Windows app that scans a folder, tools like LaunchBox may fit better.

## Do I need metadata API keys?

It runs without any but games won't match against a metadata source, so you won't get covers, descriptions, or ratings.

## Is RomM legal?

The software is legal but what you put in it depends on your jurisdiction. **We don't ship ROMs or firmware, don't help you find them, and can't give legal advice.**

## Can I run RomM on [X]?

Probably! Supported deployment paths:

- Docker Compose (Linux, macOS, Windows with WSL2)
- Unraid/Synology/TrueNAS SCALE
- Kubernetes

See [Install & Deploy](../install/index.md).

Not supported:

- Bare metal without containers (undocumented but _should_ work)
- TrueNAS CORE (FreeBSD)
- Windows without WSL

## How much RAM/CPU does it need?

- **Minimum** (small library, 1 user): 512 MB RAM, any modest CPU
- **Comfortable** (thousands of ROMs, a few users, occasional scans): 2 GB RAM, 2 cores

Heaviest CPU usage is during scans, as hashing and network-bound metadata calls may cause spikes.

## How do I update?

```sh
docker compose pull rommapp/romm
docker compose up -d romm
```

Read the [upstream release notes](https://github.com/rommapp/romm/releases) before minor or major version upgrades.

## Why can't I see a specific platform?

The platform folder name probably doesn't match a known slug. Check [Supported Platforms](../platforms/supported-platforms.md), and fix it by either renaming the folder or updating the [`system.platforms`](../reference/configuration-file.md#systemplatforms) binding in `config.yml`.

## Why are my ROMs unmatched after a scan?

Most common reasons:

- No metadata providers configured
- Filename too generic (no tags, unusual naming)
- Wrong platform detection

Full troubleshooting steps can be found in [Scanning Troubleshooting](../troubleshooting/scanning.md).

## My scan finds platforms but no games inside them

This is almost always a mount-depth issue. The scanner expects the _parent_ of your `roms/` folder mounted to `/romm/library`, not the `roms/` folder itself. If your files live at `/opt/romm/library/roms/gbc/game.gbc`, mount `/opt/romm/library` to `/romm/library`, then re-scan.

See [Folder Structure](../getting-started/folder-structure.md) and [Scanning Troubleshooting](../troubleshooting/scanning.md) for the full layout and common mount mistakes.

## Why is my metadata wrong or incomplete?

Metadata isn't owned, only pulled from third parties like IGDB and ScreenScraper. If a field is missing or wrong, the fix has to happen upstream on the provider's site. Cross-check against another provider if one is consistently off for your library.

## Why am I getting a "Configuration file not Mounted!" error?

A `config.yml` is read from `/config` at startup. If the mount/file is missing or unreadable, startup bails with this error (see [Configuration File](../reference/configuration-file.md) for the schema and an example you can drop in).

## Can I play PS3 or newer consoles in the browser?

**No.** In-browser emulation handles 4th-gen and earlier systems well. Saturn, PS1, and N64 are hit-or-miss. PSP and newer are mostly unplayable. Browser play is a bonus, as this is a library manager first, and standalone emulators remain the right tool for modern systems (see [Supported Platforms](../platforms/supported-platforms.md) for the current list).

## Why is browser emulation laggy or not loading?

A few common causes:

- **Browser**: use a Chromium-based browser (Chrome, Edge, Brave). Firefox and Safari might run EmulatorJS poorly.
- **HTTPS**: PSP and DOS cores require the site served over `https://`. Accessing by IP won't work, so you need a [Reverse Proxy](../install/reverse-proxy.md) with TLS.
- **Hardware**: EmulatorJS runs entirely in the browser, so CPU-heavy cores need a capable (modern) browser.

Full troubleshooting steps can be found in [In-Browser Play](../troubleshooting/in-browser-play.md).

## Can I share my library with friends?

Add them as users via the invite flow, then either:

- Expose your instance publicly behind a [Reverse Proxy](../install/reverse-proxy.md) with TLS.
- Keep it private and share access over a VPN or Tailscale.

See [Invitations & Registration](../administration/invitations-and-registration.md).

## Can guests browse without an account?

Absolutely, just set `KIOSK_MODE=true` in your environment variables and anonymous visitors get read-only access (see [Authentication → Kiosk mode](../administration/authentication.md#kiosk-mode)).

## How do I back up?

`mysqldump` the DB + rsync the `/romm/assets` and `/romm/config` volumes nightly. Full procedure and test-restore protocol in [Backup & Restore](../install/backup-and-restore.md).

## Can I use RomM without the internet?

You need internet for:

- First-time scan with metadata providers (they're online APIs)
- Pulling the Docker image on install or upgrade
- OIDC login (if you use a cloud IdP)

After the initial setup, browsing and playing can work offline. In-browser play downloads the emulator bundle on first launch, then caches it.

## Why is scan X slow?

Several possibilities, in rough order of likelihood:

1. Hashing large files on spinning disks.
2. Metadata providers rate-limiting (mostly ScreenScraper).
3. Many files on a network mount with high latency.

[Scanning Troubleshooting → Hash calculations are slow](../troubleshooting/scanning.md#hash-calculations-are-slow).

## When will [feature X] be added?

We don't give ETAs on individual features. Open (or upvote) an issue at [rommapp/romm](https://github.com/rommapp/romm/issues) to make the interest visible.

## I found a bug, or I need help

For bugs, open an issue at [rommapp/romm](https://github.com/rommapp/romm/issues). For questions, ask in `#romm-support` on [Discord](https://discord.gg/romm). Either way, include:

- RomM version
- Deployment (Docker Compose/Unraid/K8s/etc.)
- Your `docker-compose.yml` with credentials and API keys redacted
- Container logs (`docker logs romm`)
- Exact reproduction steps

## Who runs RomM?

A small team of maintainers plus a chunk of active community contributors. Support the project via [Open Collective](https://opencollective.com/romm) if you'd like!

## Where's can I find you?

- **Discord**: [discord.gg/romm](https://discord.gg/romm)
- **GitHub**: [rommapp/romm](https://github.com/rommapp/romm)
- **Website**: [romm.app](https://romm.app/)
- **Demo**: [demo.romm.app](https://demo.romm.app/)

## See also

- [Glossary](../reference/glossary.md) if the vocabulary is new
- [Troubleshooting](../troubleshooting/index.md) if something's broken

---

## File: docs/administration/oidc/authelia.md

---
title: OIDC with Authelia
---

# OIDC with Authelia

[Authelia](https://www.authelia.com/) is a lightweight open-source authentication and authorisation server with two-factor auth and SSO. Before starting, read the [OIDC Setup overview](index.md), as it covers the RomM-side settings common to every provider.

## 1. Prerequisites

Authelia installed and running, with its OIDC provider enabled:

- [Authelia getting started](https://www.authelia.com/integration/prologue/get-started/)
- [OIDC provider configuration](https://www.authelia.com/configuration/identity-providers/openid-connect/provider/)

## 2. Add a claims policy

In Authelia's `configuration.yml` under `identity_providers.oidc.claims_policies`, add a policy that emits the claims RomM needs (name it whatever you like):

```yaml
identity_providers:
    oidc:
        claims_policies:
            with_email:
                id_token:
                    - email
                    - email_verified
                    - groups
                    - alt_emails
                    - preferred_username
                    - name
```

Background on why this is needed: [Authelia claims parameter restoration](https://www.authelia.com/integration/openid-connect/openid-connect-1.0-claims/#restore-functionality-prior-to-claims-parameter).

## 3. Register the RomM client

Under `identity_providers.oidc.clients`, add:

```yaml
identity_providers:
    oidc:
        clients:
            - client_id: "<random>" # see note below
              client_name: "RomM"
              client_secret: "$pbkdf2-sha512$<random>" # see note below
              public: false
              authorization_policy: "two_factor" # or one_factor
              grant_types:
                  - authorization_code
              redirect_uris:
                  - "https://demo.romm.app/api/oauth/openid"
              claims_policy: "with_email" # must match the policy name above
              scopes:
                  - openid
                  - email
                  - profile
                  - groups
              userinfo_signed_response_alg: "none"
              token_endpoint_auth_method: "client_secret_basic"
```

To generate IDs and secrets, see [Authelia's FAQ](https://www.authelia.com/integration/openid-connect/frequently-asked-questions/#how-do-i-generate-a-client-identifier-or-client-secret). The full client schema is available in the [Authelia clients reference](https://www.authelia.com/configuration/identity-providers/openid-connect/clients/).

## 4. Configure RomM

In the `romm` service environment:

```yaml
environment:
    - OIDC_ENABLED=true
    - OIDC_PROVIDER=authelia
    - OIDC_CLIENT_ID=
    - OIDC_CLIENT_SECRET=
    - OIDC_REDIRECT_URI=https://demo.romm.app/api/oauth/openid
    - OIDC_SERVER_APPLICATION_URL=https://auth.example.com
    - ROMM_BASE_URL=https://demo.romm.app
```

`OIDC_REDIRECT_URI` must match what you put in `redirect_uris` exactly (scheme, host, path, no trailing slash). For role mapping from Authelia groups, see [OIDC Setup → Role mapping](index.md#role-mapping).

## 5. Set your email

In RomM → **Profile** → set your email to exactly the same address Authelia has for you. RomM matches OIDC users to existing accounts by email.



## 6. Test

Restart, navigate to `/login` and click the **Login with OIDC** button. You're redirected to Authelia → authenticate → bounced back and signed in!



If it doesn't work, head to [Authentication Troubleshooting](../../troubleshooting/authentication.md).

---

## File: docs/administration/oidc/authentik.md

---
title: OIDC with Authentik
---

# OIDC with Authentik

[Authentik](https://goauthentik.io/) is a full-featured open-source IdP with MFA, flows, and a sizeable audit/admin surface. Before starting, read the [OIDC Setup overview](index.md), as it covers the RomM-side settings common to every provider.

## 1. Prerequisites

Authentik installed and running via their [install guide](https://docs.goauthentik.io/docs/install-config/install/docker-compose).

Log in as admin and open **Admin Interface**.



## 2. Create a property mapping (Authentik 2025.10+)


!!! important "Authentik 2025.10 breaking change"
    In version 2025.10, Authentik changed the default of `email_verified` from `true` to `false`. A verified email is required, so without this property mapping, authentication silently fails.

In **Customization → Property Mappings → Create → Scope Mapping**:

- **Name**: `RomM Email Verification`
- **Scope name**: `email`
- **Expression**:

```py
return {
    "email": user.email,
    "email_verified": True,
}
```



Click **Create**. Upstream reference: [Authentik scope mappings](https://version-2025-10.goauthentik.io/add-secure-apps/providers/property-mappings/#scope-mappings-with-oauth2).

## 3. Create a provider

**Admin → Providers → Create**.



Choose **OAuth2/OpenID Provider**.



Configure:

- **Name**: `RomM OIDC Provider`
- **Authorization flow**: implicit consent
- **Redirect URIs**: `https://demo.romm.app/api/oauth/openid`
- **Scopes**: Under "Advanced protocol settings", move the property mapping you created above from "Available Scopes" to "Selected Scopes". You'll also need to make sure any existing mappings of `email` or `email_verified` are disabled. Authentik has an `email` mapping by default, so make sure to check for this and remove it if it's present.

Copy the generated **Client ID** and **Client Secret**. You'll use them as `OIDC_CLIENT_ID`/`OIDC_CLIENT_SECRET` on the app side.



Click **Create**.

## 4. Register the application

**Admin → Applications → Create**.



- **Name**: `RomM`
- **Slug**: `romm`
- **Provider**: the `RomM OIDC Provider` you just made



Click **Create**.

## 5. Configure

```yaml
environment:
    - OIDC_ENABLED=true
    - OIDC_PROVIDER=authentik
    - OIDC_CLIENT_ID=<from Authentik>
    - OIDC_CLIENT_SECRET=<from Authentik>
    - OIDC_REDIRECT_URI=https://demo.romm.app/api/oauth/openid
    - OIDC_SERVER_APPLICATION_URL=https://auth.example.com/application/o/romm
    - ROMM_BASE_URL=https://demo.romm.app
```

Note that `OIDC_SERVER_APPLICATION_URL` points at the per-application URL (`/application/o/<slug>`), not the Authentik root.

For role mapping from Authentik groups, see [OIDC Setup → Role mapping](index.md#role-mapping).

## 6. Set your email

In **Profile** → set your email to exactly the same address Authentik has for you.



## 7. Test

Restart, navigate to `/login` and click the **Login with OIDC** button. You're redirected to Authentik → authenticate → bounced back and signed in!



If it doesn't work, head to [Authentication Troubleshooting](../../troubleshooting/authentication.md).

---

## File: docs/administration/oidc/index.md

---
title: OIDC Setup
---

# OIDC Setup

OpenID Connect (OIDC) lets users sign in through an external identity provider: Authelia, Authentik, Keycloak, PocketID, Zitadel, Okta, Auth0, VoidAuth, or anything standards-compliant. Single sign-on across your homelab, no app-specific password to manage, centralised MFA, and map OIDC groups/claims to roles.


!!! note "OIDC is optional"
    The local user system works fine without OIDC. Enable OIDC when you already run an IdP and want auth to follow suit, or when you want to unify user management across multiple apps.

## How it works

1. User clicks the OIDC login button on `/login`.
2. They're redirected to your provider.
3. They authenticate (password, passkey, MFA, whatever your provider enforces).
4. Provider redirects back to `{ROMM_BASE_URL}/api/oauth/openid` with an authorisation code.
5. The code is exchanged for an ID token, the user's email and role claims are read, and either a matching local user is created on the fly (unless you've [turned off registration](#auto-provisioning)), or an existing one is logged in.

## Provider guides

Pick your provider and follow the step-by-step instructions. They all end with the same set of app-side env vars. The guides just differ on how to register the app and where to find the client ID/secret.

- [Authelia](authelia.md)
- [Authentik](authentik.md)
- [Keycloak](keycloak.md)
- [PocketID](pocketid.md)
- [Zitadel](zitadel.md)
- [VoidAuth](voidauth.md)

Not listed? Most standards-compliant OIDC providers work: Okta, Auth0, Google Workspace, Microsoft Entra, etc. Use one of the above as a template and consult your provider's docs for the registration side.

## Minimum config

Whichever provider you pick, set these in the `romm` service's environment:

```yaml
environment:
    - OIDC_ENABLED=true
    - OIDC_PROVIDER=<authelia|authentik|keycloak|pocket-id|zitadel|voidauth|generic>
    - OIDC_CLIENT_ID=<from your provider>
    - OIDC_CLIENT_SECRET=<from your provider>
    - OIDC_SERVER_APPLICATION_URL=https://auth.example.com
    - OIDC_REDIRECT_URI=https://demo.romm.app/api/oauth/openid
    - ROMM_BASE_URL=https://demo.romm.app # must match your reverse-proxy URL
```

`OIDC_REDIRECT_URI` must exactly match what you register at the provider (same scheme, host, path, no trailing slash).

## Auto-provisioning

By default, the first successful OIDC login for an email that has no matching account **creates** a local account automatically. To require accounts to exist beforehand (so only pre-provisioned users can sign in via OIDC), turn registration off:

```yaml
environment:
    - OIDC_ALLOW_REGISTRATION=false # default: true
```

With it disabled, an unknown user is rejected at login instead of getting a fresh account. New accounts land in the [default permission group](../users-and-roles.md#permission-groups) unless a role claim maps them to Admin.

## Role mapping

RomM has only two roles: **User** and **Admin** (see [Users & Roles](../users-and-roles.md#roles)). New OIDC users are provisioned as **Users**. To let your IdP promote someone to **Admin** based on group membership, set:

```yaml
environment:
    - OIDC_CLAIM_ROLES=groups # which claim to read
    - OIDC_ROLE_ADMIN=romm-admin,platform-admins # group values → Admin
```

On every login, the claim named by `OIDC_CLAIM_ROLES` is read (often `groups`, sometimes `realm_access.roles` on Keycloak, check your provider's token output). If a value matches `OIDC_ROLE_ADMIN`, the user becomes an Admin.

Roles are re-evaluated on **every login**, so demoting someone on the IdP side takes effect the next time they sign in.



!!! warning "Once `OIDC_CLAIM_ROLES` is set, users must match a mapped group"
    As soon as `OIDC_CLAIM_ROLES` is configured, RomM expects every user to match at least one mapped role group. A user whose claim matches **none** of the configured groups is rejected at login with:

    ```json
    {"detail":"User has not been granted any roles for this application."}
    ```

    To let non-admin users in, map their group to the **User** role with `OIDC_ROLE_VIEWER` (or `OIDC_ROLE_EDITOR`):

    ```yaml
    environment:
        - OIDC_CLAIM_ROLES=groups
        - OIDC_ROLE_ADMIN=romm-admin,platform-admins # → Admin
        - OIDC_ROLE_VIEWER=platform-users # non-admins → User (grants access)
    ```

    `OIDC_ROLE_VIEWER` and `OIDC_ROLE_EDITOR` no longer map to distinct roles — matching users all resolve to **User** — but they're still how you grant those users access when role claims are enabled. Point them at a group that all your non-admin users belong to. Use [permission groups](../users-and-roles.md#permission-groups) for finer-grained access; only `OIDC_ROLE_ADMIN` changes the role.

    If you *don't* set `OIDC_CLAIM_ROLES` at all, role mapping is skipped entirely and everyone is provisioned as a **User** in the default permission group.



## Autologin

To bypass the login page entirely and redirect straight to the IdP:

```yaml
environment:
    - OIDC_AUTOLOGIN=true
```

Useful when you want this to feel like a native part of your SSO stack. Combine with `DISABLE_USERPASS_LOGIN=true` to lock out local accounts entirely.


!!! warning "Keep one local admin"
    Don't set `DISABLE_USERPASS_LOGIN=true` without first confirming an admin account exists on the IdP side and can log in. If OIDC breaks and you've disabled local login, you're locked out until you fix the container env.

## RP-Initiated Logout

When set, hitting "Sign out" in RomM also signs the user out at the IdP:

```yaml
environment:
    - OIDC_RP_INITIATED_LOGOUT=true
    - OIDC_END_SESSION_ENDPOINT=https://auth.example.com/application/o/end-session/
```

The endpoint URL is provider-specific, check the per-provider guides or your IdP's docs.

## Username source

By default the local part of the email (the bit before `@`) becomes the username, but you can override it with:

```yaml
environment:
    - OIDC_USERNAME_ATTRIBUTE=preferred_username
```

## Important notes

- **Email must match** between OIDC and any existing local account, otherwise OIDC creates a new account alongside the old one.
- **HTTPS is required** in production, as OIDC will refuse to redirect to a plain-HTTP `ROMM_BASE_URL`.
- Large drift between the RomM host and IdP will lead to **clock skew** and cause ID-token validation to fail.

## Troubleshooting

Common failures and fixes live in [Authentication Troubleshooting](../../troubleshooting/authentication.md). Two of the usual suspects:

- `redirect_uri_mismatch`: `OIDC_REDIRECT_URI` differs from what's registered at the provider. Even a trailing slash can matter!
- User created but not made Admin: check `OIDC_CLAIM_ROLES` points at a claim that actually exists in the token, and that the group values match `OIDC_ROLE_ADMIN` exactly (case-sensitive).

---

## File: docs/administration/oidc/keycloak.md

---
title: OIDC with Keycloak
---

# OIDC with Keycloak

[Keycloak](https://www.keycloak.org/) is the heavyweight open-source IAM standard. Before starting, read the [OIDC Setup overview](index.md), as it covers the RomM-side settings common to every provider.

## 1. Prerequisites

Keycloak installed and running via their [getting started guide](https://www.keycloak.org/getting-started).

Log into the **Admin Console** and either create a new realm for the app or reuse an existing one.

## 2. Add a client

In the Admin Console, select your realm → **Clients** → **Create client**.

1. **Client type**: `OpenID Connect`.
2. **Client ID**: `romm` (or something unique).
3. Click **Next**.
4. On the capability page:
    - Enable **Client authentication**
    - Leave only **Standard flow** enabled
    - Click **Next**
5. Set URLs:
    - **Root URL**: `https://demo.romm.app`
    - **Valid Redirect URIs**: `https://demo.romm.app/api/oauth/openid`
    - **Web origins**: `https://demo.romm.app`
6. Save, then head to the **Credentials** tab and copy the **Client Secret**.

## 3. Configure

```yaml
environment:
    - OIDC_ENABLED=true
    - OIDC_PROVIDER=keycloak
    - OIDC_CLIENT_ID=romm
    - OIDC_CLIENT_SECRET=<from Keycloak Credentials tab>
    - OIDC_REDIRECT_URI=https://demo.romm.app/api/oauth/openid
    - OIDC_SERVER_APPLICATION_URL=https://keycloak.example.com/realms/<realm-name>
    - ROMM_BASE_URL=https://demo.romm.app
```

`OIDC_SERVER_APPLICATION_URL` must include the realm (`.../realms/<realm-name>`), not just the Keycloak root.

## 4. Set email + verify in Keycloak

In **Profile** → set your email to the same address Keycloak has for you.

On the Keycloak side, go to **Admin Console → Users** and mark each user's email as **verified**. Users with unverified emails will be rejected on login.

## 5. Test

Restart, navigate to `/login` and click the **Login with OIDC** button. You're redirected to Keycloak → authenticate → bounced back and signed in!

If a local user already exists with a matching email, they're signed into that account. Otherwise a new account is created as a regular User in the default permission group.

If it doesn't work, head to [Authentication Troubleshooting](../../troubleshooting/authentication.md).

## 6. (Optional) Disable local password logins

Force users through Keycloak:

```yaml
environment:
    - DISABLE_USERPASS_LOGIN=true
```


!!! warning
    Before flipping this, confirm at least one Admin account can sign in via OIDC, otherwise a broken OIDC flow locks you out.

## 7. (Optional) Role mapping

By default, new OIDC users come in as regular Users. To let Keycloak promote someone to **Admin** based on a role/group:

```yaml
environment:
    - OIDC_CLAIM_ROLES=groups # or realm_access.roles, depending on your token
    - OIDC_ROLE_ADMIN=romm-admin
```

Configure Keycloak's client to include the role/group claim in the ID token (usually via a **Group Membership** or **Realm Role** client scope mapper). Values in the claim are compared against `OIDC_ROLE_ADMIN` on every login, so demoting in Keycloak takes effect on the user's next sign-in.

See [OIDC Setup → Role mapping](index.md#role-mapping) for the generic version.

---

## File: docs/administration/oidc/pocketid.md

---
title: OIDC with PocketID
---

# OIDC with PocketID

[PocketID](https://github.com/stonith404/pocket-id) is a minimalist OIDC provider that **only** supports passkey authentication, with no passwords. Before starting, read the [OIDC Setup overview](index.md), as it covers the RomM-side settings common to every provider.

## 1. Prerequisites

PocketID installed, running, and your admin passkey already registered via their [PocketID setup guide](https://github.com/stonith404/pocket-id#setup).

## 2. Add the client

In PocketID admin:

1. **Application Configuration**: make sure **Emails Verified** is ticked as we now require verified emails.
2. Go to **OIDC Client** → **Add OIDC Client**.
3. Fill in:
    - **Name**: `RomM`
    - **Callback URLs**: `https://demo.romm.app/api/oauth/openid`
4. **Save**. Stay on this page as the client secret only displays **once**.
5. Copy both the Client ID and Client Secret now.

## 3. Configure RomM

```yaml
environment:
    - OIDC_ENABLED=true
    - OIDC_PROVIDER=pocket-id
    - OIDC_CLIENT_ID=<from PocketID>
    - OIDC_CLIENT_SECRET=<from PocketID>
    - OIDC_REDIRECT_URI=https://demo.romm.app/api/oauth/openid
    - OIDC_SERVER_APPLICATION_URL=https://id.example.com
    - ROMM_BASE_URL=https://demo.romm.app
```

`OIDC_SERVER_APPLICATION_URL` is the root URL of your PocketID instance.

## 4. Set your email

RomM → **Profile** → set your email to exactly the same address PocketID has for you.

## 5. Test

Restart, navigate to `/login` and click the **Login with OIDC** button. You're redirected to PocketID → authenticate → bounced back and signed in!



If it doesn't work, head to [Authentication Troubleshooting](../../troubleshooting/authentication.md).

---

## File: docs/administration/oidc/voidauth.md

---
title: OIDC with VoidAuth
---

# OIDC with VoidAuth

[VoidAuth](https://voidauth.app/) is an open-source SSO authentication and user management provider that stands guard in front of your self-hosted application. Before starting, read the [OIDC Setup overview](index.md), as it covers the RomM-side settings common to every provider.

## 1. Prerequisites

VoidAuth installed and running via their [self-hosted deployment docs](https://voidauth.app/#/?id=quick-start). We'll use the `APP_URL` from the example `compose.yml` in those docs as `https://auth.example.com`.
Your RomM instance will be referenced as `https://demo.romm.app`.

## 2. Create a new app

Log in as an admin in the VoidAuth web interface. Create a new OIDC app (e.g. `RomM`).

- **Name**: `RomM`
- **Home Page URL**: `https://demo.romm.app`
- **Logo URL**: `https://docs.romm.app/resources/romm/isotipo.png`
- **Group**: You could add a group that the user must belong to get access to your RomM instance. If left empty, any user created in your VoidAuth instance will be allowed.
- **Skip Consent** and **MFA Required**: These options can be enabled or left disabled as you prefer.
- **Client ID**: Generate an ID using the button.
- **Auth Method**: `Client Secret Basic`
- **Client Secret**: Generate a secret using the button.
- **Redirect URLs**: add `https://demo.romm.app/api/oauth/openid`
- **Response Types**: check `code`
- **Grant Types**: check `authorization_code` and `refresh_token`
- **Post Logout URL**: `https://demo.romm.app/`

Don't forget to click the `Create` button to validate your app.

## 3. Configure

```yaml
environment:
    - OIDC_ENABLED=true
    - OIDC_PROVIDER=voidauth
    - OIDC_CLIENT_ID=<from VoidAuth>
    - OIDC_CLIENT_SECRET=<from VoidAuth>
    - OIDC_REDIRECT_URI=https://demo.romm.app/api/oauth/openid
    - OIDC_SERVER_APPLICATION_URL=https://auth.example.com
    - OIDC_SERVER_METADATA_URL=https://auth.example.com/oidc/.well-known/openid-configuration
    - ROMM_BASE_URL=https://demo.romm.app
```

VoidAuth's OIDC discovery URL can be found at the top of your OIDC App page, by clicking on OIDC Endpoints.

For role mapping from VoidAuth, see [OIDC Setup → Role mapping](index.md#role-mapping).

## 4. Test

Restart, navigate to `/login` and click the **Login with VoidAuth** button. You're redirected to VoidAuth → authenticate → bounced back and signed in!

If it doesn't work, head to [Authentication Troubleshooting](../../troubleshooting/authentication.md).