查阅页。写作顺序从限制谁能读一页开始。
本页证据是 arc#4065 的合并实现(3fa375a41),以及 2026-08-15 在 ARC 2.0.0-beta.35、http://arcblock.localhost:4922/ 上对本站的本地运行。
策略写在哪里
| 位置 | 字段 | 作用范围 |
|---|---|---|
blocklet.yaml | accessDefault: public | 全站 hatch:只有写了这个哨兵,未标记的路由和记录才继承 public。缺省 = 未声明即拒绝 |
blocklet.yaml | accessPaths[] | 去掉 locale 前缀后的页面路径。最长的 match 获胜 |
blocklet.yaml collections.<type> | access | 该类型的内容详情。不是集合列表页 |
| 路由 / 页面 | access | 列表和静态页。不能拿来顶替详情上缺失的记录 |
| 内容对象 front matter | access | 仅该记录。只收紧范围,不能放宽 |
| 内容对象 front matter | preview | 被拒绝读者看到的壳。不会让正文变 public |
collections.<type>.readRole 不在这张表里。
解析
策略是天花板,顺序如下:
- 最长匹配的
accessPaths[].match(locale 前缀已去掉)。 - 内容详情上的
collections.<type>.access。列表页忽略它,避免类型级member默认锁住/articles/。 - 列表和静态页上的路由
access。详情不会把 public 列表路由当成记录本身 public。 accessDefault: public。
然后是记录:
记录 access | 效果 |
|---|---|
| 省略 | 继承范围。范围是 public 则页面 public。没有范围则未声明 → 404 |
public | 不加额外角色。打不开被锁的范围 |
none | 硬拒绝。admin 和 owner 也不能继承 |
| 任何其它字符串 | AND 收紧。调用方必须满足范围和记录上的每一个具名角色 |
调用方角色列表里的 admin 和 owner 承认任何已声明的受限资源。它们不承认未声明页或 none。
承认是对 caller.roles 的包含匹配,不是数字等级。同时带 member 和 admin 的调用方能进 admin 页。只有 member 的不能。
路径匹配:
match | 命中 |
|---|---|
/docs/internal/** | /docs/internal/runbook,不是列表 /docs/internal |
/articles/members-only | 该详情,以及 /articles/members-only/... |
| 更长的前缀 | 压过更短的 |
accessPaths:
- match: /docs/internal/**
access: admin
- match: /docs/internal/public-note
access: public判定种类
decideWebAccess 返回其一:
| kind | 何时 |
|---|---|
full | 调用方被承认 |
preview-shell | 被拒绝,且 preview: true |
promo-shell | 被拒绝,preview 不是 true,且记录可上列表 |
not-found | 未声明、none,或被拒绝且不可上列表 |
内容详情上,preview-shell 和 promo-shell 走站点 layout 现场渲染。只有 not-found 会短路成裸 404。随后 SiteServer:
- 若
preview !== false,裁第一屏试读(PAYWALL_TEASER_CHARS = 480,PAYWALL_TEASER_MAX_BLOCKS = 2,永远扣下最后一个顶层块,丢掉与 hero 标题重复的开头 H1/H2)。 - 若试读 HTML 非空,可见门文案用 preview 措辞,即使
kind是promo-shell。 - 若
preview: false,无试读。可上列表 → 只有门。不可上列表 → 404。
CJK 字符按 2 个视觉单位计。
HTTP、缓存与 SEO
| 结果 | 状态 | 缓存 | Robots |
|---|---|---|---|
| 完整 public 页 | 200 | 本次采集为 no-cache | 可索引 |
| 完整受限页(已承认的调用方) | 200 | 本次采集为 no-cache | 不强加 noindex |
| 试读 / 门 | 200 | private, no-store | X-Robots-Tag: noindex 与 <meta name="robots" content="noindex"> |
| 404 | 404 | private, no-store | 不适用 |
共享公共边缘缓存仅在 kind === "full" 且有效权限为 public 时合法。预渲染仍可能把全文写进 .web-cache/<path>/index.html。serve 闸必须在回放该文件之前跑。不要把 .web-cache 当静态站点发布。
受限 HTML 只能对外声明已写明的 SEO description 或 excerpt。从受保护正文派生的文档摘要不会进入 meta、Open Graph 或 JSON-LD。壳上的 post-hero coverImage 会被清空。受限详情拒绝 Accept: text/markdown。
现场采集,匿名 admin 夹具:
HTTP/1.1 200 OK
cache-control: private, no-store
x-robots-tag: noindex同一 URL,带 x-caller-did + x-caller-role: admin(仅本地缝):
HTTP/1.1 200 OK
cache-control: no-cache存在 BODY_MARKER_ADMIN_ONLY;没有 access-gate。
发现面与 HTML 列表
匿名 sitemap、llms.txt、MCP get 和索引查询强制 listedOnPublicList: false。
| 记录 | HTML 公共列表 | 匿名发现 |
|---|---|---|
public 或继承 public(集合 / 路径 / hatch) | 完整卡片 | 完整字段(arc#4086) |
受限且 preview: true | 推广 / 预览卡片 | 只有壳字段;正文被剥掉 |
受限且没有 preview: true | 可上列表则推广卡片 | 缺席:无 URL,无正文 |
未声明或 none | 缺席 | 缺席 |
媒体与 feed
条目本地媒体和集合 RSS 使用同一套承认函数。preview 和 promo 壳不会放出字节。公共列表卡片不是媒体承认。
本地 caller 缝
进程带 AFS_TEST_ALLOW_CALLER_HEADER=1 时:
| 头 | 作用 |
|---|---|
x-caller-did | 必需。没有它,角色头不会承认 |
x-caller-role 或 x-caller-roles | 逗号分隔的角色名 |
这是测试钩子,不是公开认证 API。