v0.0.6 - Tier-1 TCP listener + FIPS deployment documentation
This commit is contained in:
179
documents/QUBES_OS.md
Normal file
179
documents/QUBES_OS.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# QUBES_OS.md
|
||||
|
||||
## 1. Goal
|
||||
|
||||
Run `n_signer` inside a dedicated Qubes OS qube (for example `vault`-like behavior), and let caller qubes access signing via qrexec with explicit policy control.
|
||||
|
||||
This doc outlines what must be implemented/packaged for a reliable Qubes deployment path.
|
||||
|
||||
---
|
||||
|
||||
## 2. Current status (where we are now)
|
||||
|
||||
Implemented in current codebase:
|
||||
|
||||
- `nsigner` supports `--listen qrexec` and `--listen stdio`.
|
||||
- Framing is transport-agnostic and shared via length-prefixed JSON (`4-byte big-endian length + payload`).
|
||||
- In qrexec/stdio mode, server handles one framed request-response exchange.
|
||||
- Caller identity extraction supports `QREXEC_REMOTE_DOMAIN`, surfaced as `qubes:<source-vm>` when available.
|
||||
|
||||
Still missing for complete Qubes integration:
|
||||
|
||||
- qrexec service file + wrapper script artifacts.
|
||||
- dom0 qrexec policy artifacts with sane defaults.
|
||||
- install/uninstall guidance and verification flow for real Qubes deployment.
|
||||
- packaging path (`packaging/qubes/`) and docs wired into README map.
|
||||
|
||||
---
|
||||
|
||||
## 3. Architecture in Qubes
|
||||
|
||||
### 3.1 Components
|
||||
|
||||
- **Signer qube** (target): runs `nsigner` service entrypoint.
|
||||
- **Caller qube(s)**: apps/tools invoking qrexec service.
|
||||
- **dom0 policy**: controls which caller qubes may invoke signer service.
|
||||
|
||||
### 3.2 Request path
|
||||
|
||||
1. Caller qube invokes qrexec service (e.g. `qubes.NsignerRpc`).
|
||||
2. qrexec starts service command inside signer qube.
|
||||
3. Service command runs `nsigner --listen qrexec`.
|
||||
4. Caller sends framed JSON-RPC request over qrexec stdio channel.
|
||||
5. `nsigner` returns framed JSON-RPC response.
|
||||
|
||||
### 3.3 Trust and identity
|
||||
|
||||
- Source qube identity comes from `QREXEC_REMOTE_DOMAIN`.
|
||||
- `n_signer` maps caller as `qubes:<source-vm>` where available.
|
||||
- qrexec policy in dom0 remains first enforcement boundary.
|
||||
- `n_signer` policy/approval remains second boundary.
|
||||
|
||||
---
|
||||
|
||||
## 4. Required implementation tasks
|
||||
|
||||
## 4.1 Service entrypoint artifacts ✅ Implemented
|
||||
|
||||
Implemented repo artifacts:
|
||||
|
||||
- `packaging/qubes/rpc/qubes.NsignerRpc`
|
||||
- `packaging/qubes/install-service.sh`
|
||||
|
||||
`qubes.NsignerRpc` runs:
|
||||
|
||||
- `exec /usr/local/bin/nsigner --listen qrexec`
|
||||
|
||||
Install inside the signer qube:
|
||||
|
||||
```bash
|
||||
sudo sh packaging/qubes/install-service.sh
|
||||
```
|
||||
|
||||
This installs the qrexec service to `/etc/qubes-rpc/qubes.NsignerRpc` with executable permissions.
|
||||
|
||||
## 4.2 dom0 policy artifacts ✅ Implemented
|
||||
|
||||
Implemented repo artifacts:
|
||||
|
||||
- `packaging/qubes/policy.d/40-nsigner.policy`
|
||||
- `packaging/qubes/install-policy.sh`
|
||||
|
||||
Policy defaults now use explicit `ask` plus deny catch-all:
|
||||
|
||||
- `qubes.NsignerRpc * @anyvm @tag:nsigner-signer ask default_target=nsigner-vault`
|
||||
- `qubes.NsignerRpc * @anyvm @anyvm deny`
|
||||
|
||||
Install in dom0:
|
||||
|
||||
```bash
|
||||
sudo sh packaging/qubes/install-policy.sh
|
||||
```
|
||||
|
||||
This installs `/etc/qubes/policy.d/40-nsigner.policy` and prints signer-tag guidance.
|
||||
|
||||
## 4.3 Policy model inside n_signer for qubes callers ✅ Implemented
|
||||
|
||||
Current code reads caller as `qubes:<vm>` and qrexec default behavior is hardened.
|
||||
|
||||
In qrexec mode, default prompt behavior is now:
|
||||
|
||||
- `PROMPT_EVERY_REQUEST`
|
||||
|
||||
This replaces the previous permissive `PROMPT_NEVER` temporary setting.
|
||||
|
||||
## 4.4 Client helper examples ✅ Implemented
|
||||
|
||||
Added:
|
||||
|
||||
- `documents/qubes_client_examples.md`
|
||||
|
||||
Includes:
|
||||
|
||||
- shell helper example invoking `qrexec-client-vm` with framed request/response handling
|
||||
- Python helper example implementing frame encode/decode over qrexec stdio channel
|
||||
- reference to `documents/CLIENT_IMPLEMENTATION.md` for full protocol details
|
||||
|
||||
---
|
||||
|
||||
## 5. Operational runbook
|
||||
|
||||
## 5.1 Setup signer qube
|
||||
|
||||
- install `nsigner` binary at `/usr/local/bin/nsigner`
|
||||
- run `sudo sh packaging/qubes/install-service.sh`
|
||||
- verify `/etc/qubes-rpc/qubes.NsignerRpc` exists and is executable
|
||||
|
||||
## 5.2 Setup dom0 policy
|
||||
|
||||
- run `sudo sh packaging/qubes/install-policy.sh`
|
||||
- tag signer qube (example): `qvm-tags nsigner-vault add nsigner-signer`
|
||||
- reload qrexec policy per Qubes procedure/version
|
||||
|
||||
## 5.3 Verification
|
||||
|
||||
- from caller qube, invoke test request (`get_public_key`)
|
||||
- confirm signer qube receives request
|
||||
- confirm activity log displays `qubes:<source-vm>` caller prefix
|
||||
- validate deny behavior from unauthorized qube
|
||||
|
||||
## 5.4 Failure checks
|
||||
|
||||
- malformed frame -> parse error response
|
||||
- missing policy -> deny path
|
||||
- missing `QREXEC_REMOTE_DOMAIN` -> fallback identity path
|
||||
|
||||
---
|
||||
|
||||
## 6. Security requirements
|
||||
|
||||
- Never run signer service in disposable qube if mnemonic persistence is expected.
|
||||
- Prefer dedicated minimal template for signer qube.
|
||||
- Keep qrexec policy narrowly scoped (explicit source + target).
|
||||
- Require user approval for sensitive methods unless explicitly intended otherwise.
|
||||
- Log caller identity and method (without secret payload logging).
|
||||
|
||||
---
|
||||
|
||||
## 7. Documentation tasks
|
||||
|
||||
Update these after packaging lands:
|
||||
|
||||
- `README.md`
|
||||
- add Qubes deployment subsection under transport/usage
|
||||
- add `documents/QUBES_OS.md` and moved `documents/CLIENT_IMPLEMENTATION.md` in document map
|
||||
- `plans/nsigner.md`
|
||||
- mark T1 done with packaging status clearly separated
|
||||
|
||||
---
|
||||
|
||||
## 8. Definition of done (Qubes)
|
||||
|
||||
Qubes integration is considered complete when:
|
||||
|
||||
1. qrexec service artifact exists and is installable.
|
||||
2. dom0 policy artifact exists with secure default pattern.
|
||||
3. End-to-end call from allowed caller qube succeeds.
|
||||
4. Call from unauthorized qube is denied.
|
||||
5. Caller displayed as `qubes:<vm>` in activity.
|
||||
6. README + docs include full setup and troubleshooting.
|
||||
Reference in New Issue
Block a user