# cbb-sign — Operating Runbook
# Cold Bore Ballistics LLC — Internal Reference
# Classification: Confidential
# Last Updated: 2026-06-12

> **Status: TARGET (pre-provisioning).** cbb-sign is not yet deployed. These are the intended day-to-day procedures; they activate once cbb-sign is live (after cost approval). Resource names are the planned targets from `CBB_Sign_Architecture_Reference.md`.

This runbook owns **operational how-tos**. Resource facts live in the Architecture Reference; recovery lives in the Rebuild Guide; product behavior lives in the SPEC. This document assumes no prior cbb-sign experience.

---

## 1. Access and Roles

cbb-sign access is by **Entra ID group membership** — there is no separate cbb-sign login or user table.

| To let someone… | Add them to the Entra group |
|---|---|
| Send documents + track their own | `cbb-sign-sender` |
| Also create/publish/archive templates | `cbb-sign-template-manager` |
| Also see all requests, void any, view audit | `cbb-sign-admin` |

**How to add a user to a group (Entra admin center):**
1. Go to `https://entra.microsoft.com` → **Identity → Groups → All groups**.
2. Search the group name (e.g., `cbb-sign-sender`) and open it.
3. **Members → Add members → ** select the user → **Select**.
4. Group claims propagate on the user's next token (re-login if immediate).

(Programmatic alternative — Graph: `POST /groups/{id}/members/$ref`. Prefer this for scripting.)

Removing access: remove the user from the group. With no cbb-sign group, the user is authenticated but unauthorized (403).

---

## 2. Sending a Document (end-user)

1. Open `https://sign.coldboreballisticsllc.com`, sign in with the CBB Entra account.
2. **One-off:** choose "New one-off" → upload PDF or `.docx` → give it a document-type label → place fields (handed off to the engine's field editor) → add signer name+email → confirm → send.
3. **Template (common, e.g. NDA):** choose the template from the library → enter signer name+email (and ordering / wet-flag if applicable) → confirm → send.
4. The signer receives a CBB-branded email link. Track progress on the dashboard.

When all signers complete, cbb-sign files the executed PDF to OneDrive automatically and notifies the sender (email and/or Slack DM, per the sender's preference).

---

## 3. Tracking, Resending, Voiding

On the **status dashboard** (`sign.*`):

- **List/filter** requests by status, signer, template, date.
- **Open a request** to see per-signer state (not started / viewed / signed / declined) and timestamps.
- **Resend** a reminder to a signer who hasn't completed (button on the request).
- **Void** a still-pending request (cancels outstanding signing slots; recorded in audit).

A Sender sees their own requests; an Admin sees all.

---

## 4. Managing Templates (template managers / admins)

- **Create:** define the document + field layout in the engine, then register it in cbb-sign with a display name, document-type label, and signer-slot config.
- **Publish:** makes it appear in the send library. Only published templates can be sent.
- **Archive:** retires a template (no longer sendable; historical requests still reference it).

---

## 5. Wet Signature (CBB officer)

When a counterparty signs on paper:
1. On the request, mark the relevant signer slot **wet signature** (CBB-officer action).
2. The slot is skipped in the electronic flow and recorded (`signer.wet_recorded`) with the officer's identity + timestamp.
3. Optionally attach a scan of the wet-signed page (filed to `Awaiting_Wet_Signature/`).
4. The certificate notes the wet-signature assertion.

> Wet-signature legal sufficiency is an accepted risk (RISK-029) — reserve for low-risk/internal counter-signatures; re-execute electronically if sufficiency is ever questioned.

---

## 6. Deploying a New Version

cbb-sign deploys via Terraform (`cbb-infra/services/cbb/`) updating Container App revisions.

1. Build + push images: `crcbbprod.azurecr.io/cbb-sign-api:<version>` and `…/cbb-sign-ui:<version>`.
2. Run the Release Checklist (cbb-sign SDLC §7.1) — tests, CHANGELOG, security/dependency checks.
3. `terraform apply` in `services/cbb/` to roll the new revision.
4. Smoke-test against `sign.*` (login, send a test one-off, verify filing).

> Engine (Engross — the DocuSeal fork) updates: pull upstream into the public Engross repo, rebuild `…/engross/engross:cbb-<version>`, push, update the engine Container App revision. Document upstream pulls in the Engross CHANGELOG.

---

## 7. Cold Start

Both Container Apps scale to zero. After idle, the first request may take 30–60s to warm. **Expected** — wait 60s and retry before escalating. Applies to `sign.*`, `sign-api.*`, and the engine.

---

## 8. Monitoring and Alerts

- **Post-sign pipeline failure:** if filing/cert-writing fails after retries, the request goes to `error` state and an **operator alert** emails `jschwefel@coldboreballisticsllc.com` (mirrors the old Logic-App alert pattern). Remediate, then the request resolves to `filed`.
- **Where to look:** Container App logs (`ca-cbb-sign-api-prod`) for the webhook/pipeline; the dashboard's request `events` timeline for the audit trail of a specific request.

---

## 9. Common Issues

| Symptom | Likely cause | Action |
|---|---|---|
| `sign.*` slow/unavailable for ~30–60s | Cold start | Wait 60s, retry. |
| Signer didn't get the email | DocuSeal email / SendGrid | Resend from the dashboard; check SendGrid activity. |
| Upload rejected | Over size/page limit, or unsupported type | Check `MAX_UPLOAD_MB`/`MAX_PAGES`; convert/reduce; allowed: PDF/`.docx`/`.doc`/`.odt`/`.rtf`. |
| Conversion failed | Gotenberg unreachable/bad file | Check Gotenberg; re-save the source; retry. |
| Request stuck after all signed | Post-sign pipeline `error` | Check API logs + operator alert; re-trigger filing once cause cleared. |
| Document filed with wrong/raw name | A bypass send via DocuSeal admin UI (RISK-030) | Reconcile manually; reinforce "all sends via cbb-sign" policy. |
| 403 after login | User not in a cbb-sign group | Add to the appropriate group (§1). |

---

## 10. Security Operations

### 10.1 Standing secrets and rotation

All cbb-sign secrets live in `kv-cbb-shared-prod` (cbb-sign-scoped, distinct — never shared, per CLAUDE.md "Credential Sharing — VERBOTEN"). Rotation: update the KV secret; the Container Apps read at runtime. No code or config change.

### 10.2 Engross (DocuSeal) admin UI — break-glass only (RISK-030, Option B)

The Engross engine admin credential is sealed in `kv-cbb-shared-prod` as the secret **`cbb-sign-engross-breakglass`**. It exists **solely** for engine maintenance (upgrades, troubleshooting, schema migrations applied via the engine's own UI). It is **never** used to originate signing requests — doing so would bypass cbb-sign's sole-filer flow (FR-18) and audit chain (FR-21), defeating RISK-030 Option B. There are no routine engine logins; all signing is via cbb-sign.

In addition to this procedural gate, the engine itself enforces Option B in code: the `Submitter` model rejects creation when the signer email matches any User on the same account (`app/models/submitter.rb` — SIGN-46, env-gated by `CBB_SIGN_DISABLE_FILER_AS_SIGNER`, default `true`). A break-glass operator who needs to sign as themselves must set `CBB_SIGN_DISABLE_FILER_AS_SIGNER=false` for that operation only and revert immediately.

**Access policy on the secret:**
- **Read:** humans only — `jschwefel@coldboreballisticsllc.com` (current sole principal); no managed identity is granted read access.
- **Write/rotate:** humans only — same principal.
- **Audit:** Azure Key Vault diagnostic logs are enabled on `kv-cbb-shared-prod` and stream to the cbb-sign log-analytics workspace. Every `SecretGet` against `cbb-sign-engross-breakglass` produces a log entry and is treated as a rare, reviewable event.

**Break-glass procedure (when engine maintenance is required):**

1. **Confirm the trigger.** A genuine engine-maintenance event has occurred (upgrade, broken state requiring engine-side intervention, security patch that cannot wait for next image rebuild). Do **not** use this procedure to send a signing request — that is a defect, not a maintenance event.
2. **Retrieve the credential.** From a h