https://github.com/prodnull/prmana
OIDC SSH login for Linux with DPoP — replace static SSH keys with IdP-issued tokens, no gateway
https://github.com/prodnull/prmana
authentication dpop linux oidc pam security ssh
Last synced: about 2 months ago
JSON representation
OIDC SSH login for Linux with DPoP — replace static SSH keys with IdP-issued tokens, no gateway
- Host: GitHub
- URL: https://github.com/prodnull/prmana
- Owner: prodnull
- License: apache-2.0
- Created: 2026-04-13T16:52:32.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-04-23T19:43:02.000Z (about 2 months ago)
- Last Synced: 2026-04-25T12:36:49.345Z (about 2 months ago)
- Topics: authentication, dpop, linux, oidc, pam, security, ssh
- Language: Rust
- Homepage:
- Size: 5.23 MB
- Stars: 22
- Watchers: 0
- Forks: 2
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Codeowners: CODEOWNERS
- Security: SECURITY.md
- Notice: NOTICE
- Maintainers: MAINTAINERS.md
Awesome Lists containing this project
README
prmana
OIDC SSH login for Linux, without the gateway
Replace static SSH keys with short-lived IdP-issued tokens, validated directly at the host through PAM, without requiring a gateway or SSH certificate authority.
Why? •
How It Works •
Quick Start •
Documentation •
Contributing
---
## Why prmana?
SSH keys get copied, shared, and never rotated. When someone leaves, finding all their access is archaeology. Corporate MFA stops at the browser — you need it for email but not for root on production.
`prmana` bridges this gap by bringing OIDC (the same protocol behind "Sign in with Google/Microsoft/Okta") to Linux PAM, with DPoP token binding to prevent token theft.
### Why teams try it
- **Kill static SSH keys** without forcing a full access platform rollout
- **Keep direct-to-host SSH** instead of routing everything through a proxy
- **Reuse your existing IdP** (Keycloak, Okta, Azure AD, Auth0, Google) for Linux login
- **Get proof-of-possession** with DPoP — not just bearer-token login
- **Stay Linux-native** with PAM at the host boundary
- **Start small** on a few hosts before deciding whether you need more
### What makes it different
Most alternatives fall into one of three buckets:
- **Access platforms** that introduce a proxy, gateway, or managed control plane
- **SSH certificate systems** that add a CA and cert lifecycle layer
- **Simpler PAM/OIDC modules** that provide SSO but not strong proof-of-possession
`prmana` takes a different path: OIDC-backed login directly at the Linux host, with DPoP-bound authentication for stronger token handling. No gateway. No SSH CA. No static keys.
### What it is not
`prmana` is not a session recording platform, a universal infrastructure access proxy, or a full privileged-access management suite. It is a focused tool for SSH login.
---
## How It Works
```
User's Machine Linux Server
┌─────────────────────┐ ┌─────────────────────┐
│ prmana-agent │ SSH │ sshd │
│ ┌───────────────┐ │ ──────────────▶ │ ┌───────────────┐ │
│ │ OIDC token │ │ │ │ PAM module │ │
│ │ + DPoP proof │ │ │ │ (pam_prmana) │ │
│ └───────────────┘ │ │ └───────────────┘ │
└─────────────────────┘ └─────────────────────┘
│ │
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ Identity Provider │ │ Token validation │
│ (Keycloak/Okta/ │ │ + DPoP verify │
│ Azure AD/Auth0) │ │ + JWKS cache │
└─────────────────────┘ └─────────────────────┘
```
1. **`prmana-agent`** on the user's machine acquires an OIDC token from your IdP (device flow or auth code + PKCE)
2. The agent generates a DPoP proof binding the token to an ephemeral key pair
3. On SSH connection, the server's **PAM module** validates the token signature, issuer, audience, expiration, and DPoP binding
4. If validation passes and the username maps to a local account (via SSSD), authentication succeeds
### Key Components
| Component | Purpose |
|-----------|---------|
| `prmana-core` | Shared OIDC discovery and JWKS primitives |
| `pam-prmana` | PAM module — token validation, DPoP verification, break-glass |
| `prmana-agent` | Client-side agent — token acquisition, DPoP proof generation |
### Hardware Key Support
DPoP proofs can be bound to hardware security keys for stronger assurance:
- **Software signer** — ephemeral P-256 key pair (default)
- **YubiKey** — PKCS#11 via `--features yubikey`
- **TPM 2.0** — platform TPM via `--features tpm` (Linux)
---
## Quick Start
### Prerequisites
- A Linux server with OpenSSH and PAM
- An OIDC identity provider (Keycloak, Okta, Azure AD, Auth0, Google)
- Rust toolchain for building from source
### Build
```bash
cargo build --workspace
```
### Install
```bash
# Install the PAM module
sudo cp target/release/libpam_prmana.so /lib/security/pam_prmana.so
# Install the agent
cp target/release/prmana-agent ~/.local/bin/
# Configure
sudo cp examples/policy.yaml /etc/prmana/policy.yaml
# Edit policy.yaml with your issuer URL and client ID
```
### Login
```bash
# On the client machine
prmana-agent login
# Then SSH normally
ssh user@server
```
See the [installation guide](docs/installation.md) for detailed setup including IdP configuration, SSSD integration, and break-glass access.
---
## Documentation
| Guide | Description |
|-------|-------------|
| [Installation](docs/installation.md) | Full setup guide |
| [PAM Integration](docs/pam-integration.md) | PAM module configuration |
| [Security Guide](docs/security-guide.md) | Hardening and threat model |
| [Hardware Key Setup](docs/hardware-key-setup.md) | YubiKey and TPM configuration |
| [Break-Glass](docs/break-glass-validation.md) | Emergency access procedures |
| [Keycloak Reference](docs/keycloak-dpop-reference.md) | Keycloak DPoP setup |
| [Entra ID Setup](docs/entra-setup-guide.md) | Azure Entra ID configuration |
| [Community Testing](docs/community-testing-guide.md) | Testing on various platforms |
| [Threat Model](docs/threat-model.md) | STRIDE model and residual risks |
| [Competitive Threat Surface](docs/competitive-threat-surface.md) | Head-to-head security comparison vs alternatives (fact-checked against primary sources) |
### Architecture Decision Records
Design decisions are documented in [docs/adr/](docs/adr/).
---
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
```bash
# Run tests
cargo test --workspace
# Lint
cargo clippy --workspace -- -D warnings
# Format
cargo fmt --all
```
---
## Community
We'd love your feedback — questions, ideas, bug reports, or just sharing how you're using prmana.
- [GitHub Discussions](https://github.com/prodnull/prmana/discussions) — ask questions, share ideas
- [Issues](https://github.com/prodnull/prmana/issues) — bug reports and feature requests
---
## Maintained By
Built by [Chiradeep Chhaya](https://www.linkedin.com/in/chiradeepchhaya/), cybersecurity architect focused on identity and access management for production infrastructure.
All [releases are signed](SECURITY.md#binary-verification) with Sigstore (keyless) and GPG. Commits are signed with the project's GPG key.
---
## Security
See [SECURITY.md](SECURITY.md) for vulnerability reporting.
**Important**: Always configure [break-glass access](docs/break-glass-validation.md) before deploying to production. Getting locked out of servers because your IdP is down is a catastrophic failure mode.
---
## The Name
**Pramana** (Sanskrit: प्रमाण, *pramāṇa*) means "proof" and "means of knowledge" — the classical Indian epistemological framework for how you know something is true. The six pramanas are the valid means by which accurate knowledge is acquired: direct perception, inference, testimony, comparison, postulation, and proof by absence.
For this project, the connection is literal: DPoP is a pramana — cryptographic proof-of-possession, not just a bearer token asserting identity.
---
## License
Apache-2.0. See [LICENSE](LICENSE).