# How to Configure Pocket ID Passkey Login for Proxmox VE with OIDC Groups

Add Pocket ID passkey login to Proxmox VE with automatic OIDC users and groups, administrator permissions, and safe recovery access.

Author: Ruhani Rabin
Canonical: https://rabin.blog/how-to-configure-pocket-id-passkey-login-for-proxmox-ve-with-oidc-groups/
Published: 2026-07-29T16:00:18.000Z
Updated: 2026-10-11T16:32:13.000Z

I have been eyeing implementing OIDC in the homelab for a while now. After a lot of research, while I found out Authentik is much more diverse and detailed, I went with the simpler solution, which is **PocketID**. I will explain below how to connect Pocket ID to a standalone Proxmox VE installation using OpenID Connect, or OIDC.

The result is a Proxmox login flow where users authenticate through **Pocket ID using a passkey**. Proxmox users and groups are created automatically, while administrator permissions are assigned through a Pocket ID group instead of directly to individual users.

This guide is based on a working configuration using:

* Proxmox VE 9.2
* Pocket ID running as a self-hosted service. I am assuming you have already done this properly.
* Nginx Proxy Manager as the HTTPS reverse proxy
* An internal DNS server for local DNS rewrites (optional; you can do it in some other ways)
* A standalone, non-clustered Proxmox VE installation

For this tutorial, we will use the example Proxmox hostname:

```plaintext
https://proxmox.yourdomain.com
```

The example Pocket ID hostname is:

```plaintext
https://pocketid.yourdomain.com
```

> Replace all **example** domains, group names, usernames, and network addresses with values appropriate for your environment.

## Important Safety Requirements

**Warning**: **Do not remove or disable the standard Proxmox PAM realm.**

Keep these recovery methods available:

* `root@pam` login through the Proxmox web interface
* SSH key access to the Proxmox host
* Direct LAN access to the Proxmox management interface

**Pocket ID should be an additional authentication method, not the only way to administer the host.**

Keep an existing `root@pam` browser session and an SSH session open while configuring and testing OIDC.

Before changing realms or ACLs, [keep a versioned backup of the Proxmox host configuration](https://rabin.blog/proxmox-config-backup-git-version-control-pve-nodes/) as another recovery aid.

## Example Architecture

| Component          | Example                                |
| ------------------ | -------------------------------------- |
| Proxmox hostname   | `https://proxmox.yourdomain.com`       |
| Pocket ID hostname | `https://pocketid.yourdomain.com`      |
| Reverse proxy      | Nginx Proxy Manager                    |
| Proxmox upstream   | `https://PROXMOX-LAN-IP:8006`          |
| Internal DNS       | Local DNS rewrite to the reverse proxy |

If you have multiple standalone Proxmox installations, configure a separate Pocket ID OIDC client and Proxmox realm on each one. Do not assume configuration is shared between hosts.

## Step 1: Confirm Your Proxmox Version

Connect to the Proxmox host through SSH or its local shell and run:

```plaintext
pveversion -v
```

The tested installation used:

```plaintext
proxmox-ve: 9.2.0
pve-manager: 9.2.2
libpve-access-control: 9.1.1
```

Recent Proxmox VE releases support automatic OIDC user creation, automatic group creation, group claims and group-membership overwrite.

## Step 2: Check Whether OIDC Group Options Are Available

**Warning**: Do not use this command even if you found it on the internet:

```plaintext
pveum realm add --help
```

It fails because `pveum` does not use the usual subcommand `--help` format:

```plaintext
Unknown option: help
400 unable to parse option
```

The correct Proxmox command is:

```plaintext
pveum help realm add
```

To display only the relevant OIDC options, use:

```plaintext
pveum help realm add 2>&1 | grep -E \
'groups-claim|groups-autocreate|groups-overwrite|username-claim|autocreate'
```

A compatible Proxmox installation should show options including:

```plaintext
--autocreate
--groups-autocreate
--groups-claim
--groups-overwrite
--username-claim
```

You can also inspect the API schema:

```plaintext
pvesh usage /access/domains --verbose 2>&1 | grep -E \
'groups-claim|groups-autocreate|groups-overwrite|username-claim|openid'
```

## Step 3: Configure the Proxmox HTTPS URL and Reverse Proxy

The browser-facing Proxmox hostname must already work over HTTPS before configuring OIDC.

> A reverse proxy is not mandatory. However, Proxmox must have a stable, browser-accessible HTTPS URL with a trusted certificate before the OIDC client is configured.

For example, your internal DNS may resolve:

```plaintext
proxmox.yourdomain.com → REVERSE-PROXY-LAN-IP
```

Nginx Proxy Manager then forwards the request to:

```plaintext
https://PROXMOX-LAN-IP:8006
```

### Configure Nginx Proxy Manager

The Nginx Proxy Manager proxy host for `proxmox.yourdomain.com` should use:

| Setting                | Value                    |
| ---------------------- | ------------------------ |
| Domain Name            | `proxmox.yourdomain.com` |
| Scheme                 | `https`                  |
| Forward Hostname or IP | `PROXMOX-LAN-IP`         |
| Forward Port           | `8006`                   |
| Websockets Support     | Enabled                  |
| Cache Assets           | Disabled                 |
| Force SSL              | Enabled                  |
| HTTP/2 Support         | Enabled                  |

> WebSocket support is required for Proxmox noVNC, browser terminals, and interactive console sessions.

If the existing proxy already loads Proxmox correctly and consoles work, avoid adding unnecessary custom directives.

If Nginx Proxy Manager reports upstream certificate verification errors because Proxmox uses a self-signed certificate, the following directive may be added to the proxy host’s Advanced section:

```plaintext
proxy_ssl_verify off;
```

This affects only the connection between Nginx Proxy Manager and the Proxmox upstream. Browser-facing HTTPS should still use a valid certificate.

Do not place an additional Nginx Proxy Manager Access List or forward-auth layer in front of Proxmox. Proxmox is already the OIDC client, and a second authentication layer can interfere with redirects, API requests, and WebSocket connections.

Confirm that the Proxmox hostname works without a certificate warning:

```plaintext
curl -I https://proxmox.yourdomain.com/
```

Also confirm that the Proxmox host can reach Pocket ID directly:

```plaintext
curl -fsS \
  https://pocketid.yourdomain.com/.well-known/openid-configuration |
  python3 -m json.tool
```

This test must work from the Proxmox host, not only from a workstation browser. Proxmox performs server-side OIDC discovery and token exchange.

## Step 4: Create Pocket ID Groups

Open Pocket ID and create two user groups.

For example:

```plaintext
proxmox_users
proxmox_admins
```

The groups have separate purposes:

* `proxmox_users` allows ordinary access to this Proxmox installation.
* `proxmox_admins` identifies users who should receive the Proxmox Administrator role.

Add your initial administrator account to both groups.

Use simple lowercase group names containing letters, numbers, hyphens, or underscores. Most importantly, record the exact spelling.

Proxmox treats these as different group names:

```plaintext
proxmox-admins
proxmox_admins
```

A hyphen and an underscore are not interchangeable.

## Step 5: Create a Dedicated Pocket ID OIDC Client

In Pocket ID, open the OIDC client section and create a new client.

Use a descriptive name such as:

```plaintext
Proxmox
```

Set the callback URL to exactly ( **no trailing slash**):

```plaintext
https://proxmox.yourdomain.com
```

Do not use any of these variations:

```plaintext
https://proxmox.yourdomain.com/
https://proxmox.yourdomain.com:8006
https://PROXMOX-LAN-IP:8006
https://proxmox.yourdomain.com/callback
https://proxmox.yourdomain.com/api2/json/access/openid/login
```

The callback must match the browser-facing Proxmox base URL.

Under **Allowed User Groups**, select:

```plaintext
proxmox_users
proxmox_admins
```

A new Pocket ID OIDC client does not allow anyone to sign in until you select the allowed users or groups. Use **Unrestrict** only if you intentionally want every Pocket ID user to access this Proxmox login.

After saving the client, securely copy:

* Client ID
* Client Secret

Do not publish either value in screenshots, terminal output, or documentation. If any part of the client secret becomes visible, rotate it in Pocket ID and update the Proxmox realm.

## Step 6: Add the OpenID Connect Realm in Proxmox

Log in to `https://proxmox.yourdomain.com` using `root@pam`.

Navigate to:

```plaintext
Datacenter
→ Permissions
→ Realms
→ Add
→ OpenID Connect Server
```

Enter the following settings:

| Field                   | Value                                |
| ----------------------- | ------------------------------------ |
| Issuer URL              | `https://pocketid.yourdomain.com`    |
| Realm                   | `pocketid`                           |
| Client ID               | Client ID generated by Pocket ID     |
| Client Key              | Client secret generated by Pocket ID |
| Scopes                  | `openid profile email groups`        |
| Autocreate Users        | Enabled                              |
| Username Claim          | `username`                           |
| Autocreate Groups       | Enabled                              |
| Groups Claim            | `groups`                             |
| Overwrite Groups        | Enabled                              |
| Query userinfo endpoint | Enabled                              |
| Default                 | Disabled during initial testing      |

Leave these fields empty unless your identity provider specifically requires them:

* ACR Values
* Audiences
* Prompt

![Add OpenID Connect Realm in Proxmox](https://rabin.blog/_astro/add-the-openid-connect-realm-in-proxmox.BHpwKGfN_Z28twVu.webp)

## Why Use the Username Claim?

✅ Use:

```plaintext
username
```

This creates a Proxmox account similar to:

```plaintext
youruser@pocketid
```

Using the email claim would create a longer account name similar to:

```plaintext
user@example.com@pocketid
```

The Proxmox interface offers supported username mappings such as `username`, `email` and the OIDC subject. Do not manually enter `preferred_username` when the Proxmox interface provides `username`.

## Step 7: Verify the Saved Realm

On the Proxmox host, inspect the realm configuration:

```plaintext
grep -A20 '^openid: pocketid' /etc/pve/domains.cfg
```

A working configuration should resemble:

```plaintext
openid: pocketid
        client-id REDACTED
        issuer-url https://pocketid.yourdomain.com
        autocreate 1
        client-key REDACTED
        default 0
        groups-autocreate 1
        groups-claim groups
        groups-overwrite 1
        query-userinfo 1
        scopes openid profile email groups
        username-claim username
```

Always redact the client ID and client key before sharing this output publicly.

## Step 8: Understand Proxmox OIDC Group Names

This is one of the most important details in the configuration.

Proxmox does not use the Pocket ID group name unchanged. It appends the OIDC realm name as a suffix.

For example, Pocket ID sends:

```plaintext
proxmox_admins
```

The Proxmox realm is:

```plaintext
pocketid
```

Proxmox therefore creates:

```plaintext
proxmox_admins-pocketid
```

The ordinary user group becomes:

```plaintext
proxmox_users-pocketid
```

Do not guess these final names. Perform the first login and inspect the automatically created groups.

## Step 9: Perform the First Passkey Login

![You should select the pocketid option in the login screen of Proxmox VE.](https://rabin.blog/_astro/select-the-pocketid-option-in-the-login-screen-of-proxmox-ve.Ci8DIBVF_ZtIflY.webp)

Keep the existing `root@pam` browser session open.

1. Open a private or incognito browser window.
2. Visit `https://proxmox.yourdomain.com`.
3. Select the `pocketid` realm.
4. Click the OpenID login button.
5. Confirm that the browser redirects to the correct Pocket ID domain.
6. Authenticate with a registered passkey.
7. Confirm that the browser returns to `https://proxmox.yourdomain.com`.

![Now perform the login via Pocket ID.](https://rabin.blog/_astro/perform-the-first-passkey-login-via-pocketid.CxUmmM1g_Z20SLiv.webp)

At this stage, authentication may succeed while no nodes or resources are visible. This does not necessarily mean OIDC failed.

It usually means the new user has been created successfully but does not yet have a Proxmox permission assignment.

## Step 10: Verify the Automatically Created User

On the Proxmox host, run:

```plaintext
pveum user list | grep '@pocketid'
```

A successfully created account should appear similar to:

```plaintext
youruser@pocketid
```

Inspect the relevant user and group entries:

```plaintext
grep -E \
'proxmox_(users|admins)-pocketid|@pocketid' \
/etc/pve/user.cfg
```

Example:

```plaintext
user:youruser@pocketid:1:0:First:Last:user@example.com:::
group:proxmox_admins-pocketid:youruser@pocketid::
group:proxmox_users-pocketid:youruser@pocketid::
```

This output reveals the exact group names Proxmox created.

## Step 11: Assign Administrator Permission to the Imported Group

Assign permissions to the automatically created group, not directly to the user.

For the example group:

```plaintext
proxmox_admins-pocketid
```

Run:

```plaintext
pveum acl modify / \
  --group proxmox_admins-pocketid \
  --role Administrator
```

The path `/` applies the role to the entire Proxmox installation.

Verify the permission:

```plaintext
pveum acl list | grep pocketid
```

The result should resemble:

```plaintext
/    Administrator    group    proxmox_admins-pocketid
```

## Avoid Creating the Wrong Group

**Tip**: One easy mistake is manually creating a group with **hyphens** while Pocket ID sends a group containing **underscores**.

For example, this manually created group:

```plaintext
proxmox-admins-pocketid
```

is different from the automatically imported group:

```plaintext
proxmox_admins-pocketid
```

If the Administrator ACL is assigned to the wrong group, authentication succeeds but the user may see no Proxmox nodes or resources.

The solution is to assign the ACL to the exact group shown in `/etc/pve/user.cfg`:

```plaintext
pveum acl modify / \
  --group proxmox_admins-pocketid \
  --role Administrator
```

After confirming that the correct ACL works, remove any incorrect ACL and unused lookalike group.

Inspect the supported deletion syntax before removing an ACL:

```plaintext
pveum help acl delete
```

The unused group can be removed with:

```plaintext
pveum group delete proxmox-admins-pocketid
```

Never delete the group that contains the active OIDC user.

## Step 12: Sign In Again and Verify Access

1. Sign out of the Pocket ID Proxmox session.
2. Open a fresh private browser window.
3. Visit `https://proxmox.yourdomain.com`.
4. Select the `pocketid` realm.
5. Authenticate with a passkey.

The Proxmox node and permitted resources should now appear.

The permission chain is:

```plaintext
Pocket ID user
→ Pocket ID proxmox_admins group
→ OIDC groups claim
→ Proxmox proxmox_admins-pocketid group
→ Administrator role on /
```

No direct user ACL is required.

## How Automatic Group Updates Work

The realm has these options enabled:

```plaintext
groups-autocreate 1
groups-overwrite 1
```

`groups-autocreate` allows Proxmox to create groups received through the OIDC `groups` claim.

`groups-overwrite` makes the identity provider authoritative for that OIDC user’s group membership during login.

For example, if a user is removed from `proxmox_admins` in Pocket ID, the user should lose membership in `proxmox_admins-pocketid` after the next successful login.

This makes permission management cleaner than assigning Administrator directly to individual OIDC accounts.

## Step 13: Verify Passkey Authentication

To test the complete passkey flow rather than an existing Pocket ID browser session:

1. Sign out of Pocket ID.
2. Open a new private browser window.
3. Visit the Proxmox login page.
4. Select the `pocketid` realm.
5. Confirm the redirect goes to the legitimate Pocket ID hostname.
6. Complete the passkey prompt.
7. Confirm the browser returns to Proxmox.
8. Confirm the logged-in user ends with `@pocketid`.

Pocket ID handles the passkey authentication. Proxmox does not receive or store the passkey.

![Confirm in a Private Browser window that after entering the passkey it goes inside Proxmox properly.](https://rabin.blog/_astro/confirm-in-a-private-browser-window-that-after-entering-the-passkey-it-goes-inside-proxmox-properly.NAHvmxGo_PbWPR.webp)

## Why the Proxmox Host Shell Asks for a Login

**Tip**: An OIDC user is a Proxmox application identity. It is not automatically a local Linux account on the Proxmox host.

For example:

```plaintext
youruser@pocketid
```

may exist in the Proxmox access-control database, but it does not exist in:

```plaintext
/etc/passwd
```

Therefore, opening the host shell from the Proxmox interface while signed in through OIDC may display a Linux login prompt.

This differs from a `root@pam` session because `root@pam` maps to the real local Linux `root` account.

This is not an OIDC configuration failure.

A practical operating model is:

| Task                               | Authentication                        |
| ---------------------------------- | ------------------------------------- |
| Proxmox web interface              | Pocket ID passkey                     |
| VM and LXC administration          | Pocket ID passkey                     |
| Guest console access               | Pocket ID passkey                     |
| Proxmox host shell                 | `root@pam` or local Linux credentials |
| Direct host maintenance            | SSH key                               |
| Identity-provider failure recovery | `root@pam` or SSH key                 |

## Step 14: Test Break-Glass Recovery

After Pocket ID login works, test what happens when Pocket ID is unavailable.

Before stopping Pocket ID, verify both recovery methods:

```plaintext
ssh root@PROXMOX-LAN-IP
```

Also verify that `root@pam` still works through the Proxmox web interface.

Stop the Pocket ID container or service using the command appropriate for your environment.

For a Proxmox LXC container, that may resemble:

```plaintext
pct shutdown CONTAINER-ID --timeout 60
pct status CONTAINER-ID
```

Test the following:

* Pocket ID login should fail because the identity provider is unavailable.
* `root@pam` login should continue to work.
* SSH key access to the Proxmox host should continue to work.

Restart Pocket ID:

```plaintext
pct start CONTAINER-ID
pct status CONTAINER-ID
```

Confirm that the Proxmox host can reach OIDC discovery again:

```plaintext
curl -fsS \
  https://pocketid.yourdomain.com/.well-known/openid-configuration \
  >/dev/null &&
echo "Pocket ID discovery reachable"
```

Then repeat the private-window passkey login.

## Troubleshooting

### OIDC Login Works but No Proxmox Nodes Are Visible

This usually means authentication succeeded, but the user has no ACL.

Check the imported groups:

```plaintext
grep -E 'pocketid|@pocketid' /etc/pve/user.cfg
```

Assign the Administrator role to the exact imported administrator group:

```plaintext
pveum acl modify / \
  --group EXACT_IMPORTED_GROUP_NAME \
  --role Administrator
```

Do not assume hyphens and underscores are equivalent.

### Redirect URI Mismatch

Confirm that the Pocket ID callback is exactly:

```plaintext
https://proxmox.yourdomain.com
```

**Warning**: Do not append a slash, port number, or callback path.

### User is created, but Groups Are Missing

Verify that the realm contains:

```plaintext
scopes openid profile email groups
groups-claim groups
groups-autocreate 1
```

Also verify that the Pocket ID user belongs to the expected groups and that those groups are allowed to use the OIDC client.

### Proxmox Interface Works but noVNC Does Not

Check that Nginx Proxy Manager has WebSocket support enabled.

**Also confirm that no access list or second authentication proxy is intercepting WebSocket requests.**

### Inspect Proxmox Authentication Logs

```plaintext
journalctl -f \
  -u pveproxy \
  -u pvedaemon
```

Recent OIDC-related messages can be filtered with:

```plaintext
journalctl --since "-10 minutes" |
grep -Ei 'openid|oidc|authentication|realm|group'
```

### Inspect Users, Groups and Permissions

```plaintext
pveum realm list
pveum user list
pveum group list
pveum acl list
```

## Final Verification Checklist

### Pocket ID

* The ordinary user group exists.
* The administrator group exists.
* The administrator account belongs to both groups.
* A dedicated OIDC client exists for this Proxmox installation.
* The callback is exactly `https://proxmox.yourdomain.com`.
* The client ID and secret are stored securely.

### Proxmox Realm

* The realm ID is `pocketid`.
* The issuer URL is the Pocket ID base URL.
* The username claim is `username`.
* The scopes are `openid profile email groups`.
* Automatic user creation is enabled.
* The groups claim is `groups`.
* Automatic group creation is enabled.
* Group overwrite is enabled.
* The userinfo endpoint option is enabled.
* The PAM realm remains available.

### Permissions

* The OIDC user was created successfully.
* The exact imported group names were checked in `/etc/pve/user.cfg`.
* The Administrator ACL is assigned to the actual imported administrator group.
* No direct Administrator ACL is required for the individual user.
* No unused lookalike group remains with hyphens or underscores in the wrong places.

### Reverse Proxy

* The Proxmox hostname has a valid certificate.
* Nginx Proxy Manager forwards to HTTPS port 8006.
* WebSocket support is enabled.
* noVNC and browser consoles work.
* No second authentication layer is placed in front of Proxmox.

### Recovery

* `root@pam` remains usable.
* SSH key access remains usable.
* Pocket ID login fails safely while Pocket ID is stopped.
* Local PAM and SSH access continue working while Pocket ID is unavailable.
* Passkey login works again after Pocket ID restarts.

## Conclusion

Pocket ID provides a clean passkey-based login experience for Proxmox VE without replacing the local PAM or SSH recovery paths.

The most important implementation detail is group naming. Proxmox automatically appends the realm suffix to groups received from Pocket ID. Always inspect the generated groups after the first login instead of manually guessing their final names.

Once the correct imported group receives the Administrator ACL, Pocket ID group membership becomes the source of authorization. Users can then be granted or removed from Proxmox administration through Pocket ID without assigning permissions directly to each Proxmox account.

OIDC should remain an additional management layer. Keep `root@pam` and SSH keys available so that Proxmox remains recoverable even when Pocket ID or the reverse proxy is unavailable.

Let me know if this helped or if you have implemented something similar like with Authentik.
