# Licensing Guide

`word-editor` uses two separate license concepts:

- Source license: the repository source code is AGPL-3.0-only.
- Runtime authorization: production use is gated by an ES256-signed `office-preview-license.json`, a public P-256 key set, and the browser policy gate.

The runtime authorization file and verification public keys are public deployment material. The P-256 signing private key, registrar grants, customer grants, and issuance ledgers are private materials and must never be committed.

## Current Runtime License

The canonical runtime license is root-signed:

```text
licenseId: word-editor-root-pages-20260721
scope: root:word-editor
holder: word-editor
origin: https://docx-editor.pages.dev
feature: docx
```

Local development origins are also included:

```text
http://127.0.0.1:*
http://localhost:*
```

This license is not derived from an enterprise customer registrar grant. It intentionally has no `parentGrantId`, no `parentHolder`, and no `issuedBy: office-preview-enterprise-registrar`.

## Reissuing The Root Runtime License

The ES256 signing private key stays outside the repository with mode `0600`:

```text
~/.office-preview-license/word-editor-license-es256-2026-07.private.json
```

Issue a new runtime license:

```bash
npm run license:issue-root
```

Optional environment overrides:

```bash
WORD_EDITOR_DEPLOY_ORIGIN=https://docx-editor.pages.dev \
WORD_EDITOR_LICENSE_VALID_DAYS=365 \
WORD_EDITOR_LICENSE_ID=word-editor-root-pages-20260721 \
npm run license:issue-root
```

## Runtime Enforcement Flow

1. The page imports `auth/word-editor-license-runtime.mjs`.
2. The runtime fetches `office-preview-license.json` and the public P-256 key set.
3. Browser WebCrypto verifies the protected JWS-style ES256 signature before claims are read.
4. The policy gate validates product, time window, origin, edition, and feature in a closure.
5. The gate installs immutable globals under `flyfish.wordEditor.licenseGate.v1`.
6. `<word-editor license-required license-feature="docx">` mounts only after `docx` authorization succeeds.

## Security Rules

- Commit `office-preview-license.json` only when it is a public runtime authorization for the intended deployment.
- Do not commit ES256 private keys or any JWK containing `d`.
- Reject the retired HMAC v2 envelope; there is no compatibility fallback.
- Do not commit enterprise registrar grants.
- Do not commit customer grants or private ledgers.
- Do not deploy an enterprise registrar grant as a runtime license.

---

# 授权指南

`word-editor` 有两类不同的授权概念：

- 源码许可证：仓库源码使用 AGPL-3.0-only。
- 运行授权：生产使用由 ES256 签名的 `office-preview-license.json`、P-256 公钥集和浏览器策略门禁控制。

运行授权文件和验签公钥是可公开部署材料。P-256 签名私钥、注册机 grant、客户 grant 和签发账本都是私有材料，不能提交到仓库。

## 当前运行授权

当前标准运行授权为根签发：

```text
licenseId: word-editor-root-pages-20260721
scope: root:word-editor
holder: word-editor
origin: https://docx-editor.pages.dev
feature: docx
```

同时允许本地开发 origin：

```text
http://127.0.0.1:*
http://localhost:*
```

该授权不是从企业客户注册机 grant 派生，不包含 `parentGrantId`、`parentHolder` 或 `issuedBy: office-preview-enterprise-registrar`。

## 重新签发根运行授权

ES256 签名私钥以 `0600` 权限保存在仓库外：

```text
~/.office-preview-license/word-editor-license-es256-2026-07.private.json
```

签发新运行授权：

```bash
npm run license:issue-root
```

可选环境变量：

```bash
WORD_EDITOR_DEPLOY_ORIGIN=https://docx-editor.pages.dev \
WORD_EDITOR_LICENSE_VALID_DAYS=365 \
WORD_EDITOR_LICENSE_ID=word-editor-root-pages-20260721 \
npm run license:issue-root
```

## 运行时门禁流程

1. 页面导入 `auth/word-editor-license-runtime.mjs`。
2. runtime 拉取 `office-preview-license.json` 和 P-256 公钥集。
3. 浏览器 WebCrypto 在读取 claims 前校验受保护的 JWS 风格 ES256 签名。
4. 闭包内策略门禁校验产品、时间窗、origin、版本和功能。
5. 门禁安装不可变的 `flyfish.wordEditor.licenseGate.v1` 全局对象。
6. `<word-editor license-required license-feature="docx">` 仅在 `docx` 授权通过后挂载。

## 安全规则

- 只有面向目标部署的公开运行授权可以提交为 `office-preview-license.json`。
- 不提交 ES256 私钥或任何包含 `d` 的 JWK。
- 严格拒绝旧 HMAC v2 授权，不保留兼容回退。
- 不提交企业注册机 grant。
- 不提交客户 grant 或私有账本。
- 不把企业注册机 grant 当作运行授权部署。
