首页/新闻资讯/正文详情

IronClaw Reborn 机密服务契约:基于租户作用域的加密存储与一次性租赁(SecretStore / CredentialBroker)解析

发布时间:2026/9/25 5:16:12 来源:云帆数科 栏目:资讯中心
IronClaw Reborn 机密服务契约:基于租户作用域的加密存储与一次性租赁(SecretStore / CredentialBroker)解析
人工智能AI 应用交互助手AI Agent【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址https://gitcode.com/gh_mirrors/iro/ironclaw点击查看免费下载IronClaw 是一个以隐私、安全与可扩展性为核心定位的 Agent OS其 Reborn 架构把机密secrets从运行时中剥离为独立的服务边界。本文以docs/internal/reborn/contracts/secrets.md契约为骨架结合crates/substrates/ironclaw_secrets的源码与契约测试完整解析该机密服务的存储、加密、一次性租赁one-shot lease、凭证经纪credential broker与运行时注入边界帮助你理解原始密钥材料在整条链路中只可被读取一次这一核心不变量是如何在代码层面落地的。1. 服务定位把不透明句柄变成一次性访问租约ironclaw_secrets是 Reborn 中有作用域scoped的机密元数据与租赁服务。它解决的核心问题是宿主侧持有的是不透明的SecretHandle如host_api定义的句柄形状而运行时侧真正需要的是拿到原始密钥材料且只能用一次的能力。契约给出了一条明确的转换链ResourceScope SecretHandle - SecretStore::lease_once(...) - SecretLease - SecretStore::consume(...) - SecretMaterial exactly once即作用域加句柄 → 申请一次性租约 → 恰好消费一次 → 得到原始材料。这条链在 secret_store.rs 中有完整实现lease_once创建租约、consume通过 CAScompare-and-swap原子地把租约从Active推进到Consumed并返回解密后的材料第二次consume同一租约会得到LeaseConsumed错误见 lib.rs 的错误定义以及 secret_store_contract.rs 中一次性消费的契约测试。边界责任划分契约原文非常清晰host_api - opaque SecretHandle and Action::UseSecret shapes secrets - scoped storage, metadata, and one-shot leases authorization - whether a caller may use a SecretHandle capabilities - caller-facing workflow; fails closed on InjectSecretOnce host_runtime - built-in obligation handler leases/stages one-shot secret material runtimes - consume injected values only after host-side authorization换句话说本 crate不决定授权、不运行审批流、不接触网络、不发审计事件、不做产品面编排它只提供元数据与租赁/消费原语任何把机密注入到运行时请求中的具体组装都由宿主运行时组合层完成。crate 的 README 也明确提示如果需要一个被注入到运行时调用里的机密那应该走内核的 obligation handlingironclaw_host_runtimestaging而不是直接读 store。2. 公开契约与边界小而封闭的 trait 面契约列出的公开类型如下SecretMaterial SecretMetadata SecretLeaseId SecretLeaseStatus SecretLease SecretStoreError SecretStore SecretStore // durable when backed by libSQL/Postgres RootFilesystem; // SecretStore::ephemeral() is the volatile // InMemoryBackend construction (§4.3 — replaced InMemorySecretStore) CredentialAccountStore CredentialSessionStore InMemoryCredentialBroker CredentialBroker // durable when backed by libSQL/Postgres RootFilesystem关键设计点SecretMaterial是secrecy::SecretString的重导出见 lib.rs。对原始值的访问必须显式走ExposeSecret元数据、租约记录与错误永远不携带原始值。SecretMetadata只含scope、handle、expires_at契约测试secret_store_returns_metadata_without_secret_material专门断言format!({metadata:?})中不含密钥明文。SecretStore有两条实现线持久化的SecretStore由 libSQL/Postgres 的RootFilesystem支撑与易失的SecretStore::ephemeral()InMemoryBackend构造。SecretStore::ephemeral()的源码注释明确写着取代被删除的InMemorySecretStore契约 §4.3它使用租户重写tenant-rewriting的/secrets挂载解析器与临时主密钥。CredentialBroker同时实现CredentialAccountStore与CredentialSessionStore两个 trait文件系统实现见 secret_store.rs与内存版InMemoryCredentialBroker保持形状一致并保持 account/session 的外键关系在持久化层完整。从源码结构看本 crate 的依赖锥被刻意隔离它只依赖ironclaw_filesystem与ironclaw_host_api同层同族边外加aes-gcm、hkdf、sha2、secrecy、secret-service/security-frameworkkeychain等外部 crate这是把 crypto/keychain 依赖锥隔离出其他 crate的刻意安排。3. 作用域与隔离规则没有全局句柄查找所有操作都接收一个ResourceScope。V1 的内存与文件系统实现按tenant/user/agent/project SecretHandle键控机密租约则按完整调用上下文 SecretLeaseId键控。契约明确了六条规则没有全局句柄查找另一个 tenant/user/agent/project 下同名的SecretHandle是不同的机密跨作用域消费租约返回UnknownLease缺失机密返回UnknownSecret且不会创建租约已消费的租约不能再消费已撤销的租约不能消费。在文件系统实现中隔离是结构性的/secrets挂载别名由组合层解析为/tenants/tenant_id/users/user_id/secrets因此存储代码根本不需要记忆租户/用户身份agent/project 子作用域留在路径中同时 AAD见下文加密一节把密文绑定到同一个(tenant, user, agent, project, handle)元组实现路径层 解密层双保险的 fail-closed。路径布局alias-relative/secrets/agents/agent/projects/project/secrets/handle.json /secrets/agents/agent/projects/project/secret-leases/lease_id.json /secrets/agents/agent/projects/project/credential-accounts/account_id.json /secrets/agents/agent/projects/project/credential-sessions/session_id.json契约测试secret_store_isolates_same_handle_between_tenants、secret_store_isolates_same_handle_between_users_and_projects分别验证了跨租户、跨用户、跨项目下同名句柄的相互隔离与跨作用域消费返回is_unknown_lease()的行为。4. 当前 API 流程与使用姿势契约给出了最小可用流程let metadata secrets .put(scope.clone(), handle.clone(), SecretMaterial::from(token)) .await?; let lease secrets.lease_once(scope, handle).await?; let material secrets.consume(scope, lease.id).await?;要点metadata与lease只可安全地作为元数据记录日志不含机密值material是唯一的原始值载体应只停留在请求它的那条窄注入路径内。SecretStore::put(...)是受信任原语供 setup、组合、迁移或已有权管理密钥材料的存储代码使用不是运行时/插件 API也刻意不做授权。在SecretStore文件系统实现中consume使用cas_update在每次 CAS 重试时以FnMut方式应用更新Active租约会先读回密文、用 AAD 解密然后原子地把租约推进为Consumed并返回材料Consumed/Revoked/Expired状态分别映射到LeaseConsumed/LeaseRevoked/LeaseExpired错误secret_store.rs。过期推进采用写入过期标记 返回LeaseExpired的最佳努力路径且 CAS 重试不会重复写入。除了上述基础流程源码还提供两个进阶原语put_versioned/SecretCasExpectation用于密钥轮换类场景典型如 linked-device 会话密钥。调用方携带自己读到的版本store 拒绝覆盖任何更新的版本竞争失败是一个结果SecretCasWriteOutcome::Conflict而非错误调用方自行决定重载合并lib.rs。put_if_absent原子不存在才创建契约测试concurrent_put_if_absent_preserves_exactly_one_winner用两个并发任务验证了恰好一个写入者胜出、败者拿到false。4.1 加密与密钥派生AES-256-GCM 逐记录 HKDF加密实现在 crypto.rs每个记录使用独立的 HKDF-SHA256 盐32 字节从主密钥派生出 32 字节记录密钥再用AES-256-GCM加密12 字节随机 nonce 16 字节 tag 内嵌在密文头部。AAD附加认证数据绑定记录身份encrypt(plaintext, aad)中aad不加密但被 GCM 认证标签覆盖解密必须传入相同 AAD否则返回SecretError::DecryptionFailed。这样即使攻击者拥有数据库写权限也无法把(encrypted_value, key_salt)从一行搬到另一行。不同存储形状使用域分隔的 AAD 构造器AAD_DOMAIN_SECRET_RECORDDB 密钥记录、AAD_DOMAIN_CREDENTIAL_ACCOUNT、AAD_DOMAIN_CREDENTIAL_SESSION、AAD_DOMAIN_FILESYSTEM_SECRET文件系统机密。build_aad使用(u64-be 长度前缀 || 字节)的编码域标签防止跨形状重放凭证账户密文无法被当作机密记录密文重放。文件系统机密的 AAD 只绑定owner scopetenant/user/agent/project刻意排除 mission/thread/invocation这样同一 owner 下的跨调用读取可以成功路径层本来允许而跨 owner 读取在路径层与 AAD 层都 fail closed。主密钥校验validate_master_key_material要求长度 ≥ 32 字节且不同字节数 ≥ 8KEY_MIN_DISTINCT_BYTES防止运维粘贴 32 个0、32 个a或短字母重复这类低熵密钥。SecretsCrypto::ephemeral()为易失 store 生成随机单进程主密钥。4.2 主密钥来源环境变量与 OS Keychain主密钥解析逻辑在 keychain.rs查找顺序为显式设置的SECRETS_MASTER_KEY环境变量空值被忽略优先否则查询 OS keychainmacOS 用 security-frameworkLinux 用 secret-service / GNOME Keyring / KWallet服务名为ironclaw、账户名为master_key。generate_master_key()/generate_master_key_hex()生成 32 字节随机主密钥。契约特别强调store 就绪必须 fail closed——当配置的主密钥缺失或畸形时不得报告就绪。早期基于文件系统存储的 key-check 哨兵sentinel记录已随 tenant-awareScopedFilesystem重构移除主密钥不匹配会在首次按租户解密操作时暴露而不是在启动时见 secret_store.rs 的注释。4.3 持久化 DTO磁盘上只有密文文件系统实现内部使用私有 DTOStoredSecret含encrypted_value、key_salt、expires_at、StoredLease、StoredAccount、StoredSession。StoredAccount对整个CredentialAccount记录含secret_handles、allowed_targets、redacted 元数据整体加密因为integration-shape 信息也不该对拥有裸存储访问权限的人可见。所有记录都携带RecordKindsecret_record/secret_lease/credential_account/credential_session让 Postgres/libSQL 等 record-aware 后端能区分 schema 家族、拒绝盲写。文件里没有任何路径会以明文写密钥材料。5. 凭证经纪CredentialBroker账户与会话的带界管理CredentialBroker持久化与InMemoryCredentialBroker易失提供两类凭证CredentialAccount一个可签发会话的账户包含provider_or_extension_id、statusActive/Expired/Revoked、secret_handles、allowed_targets由CredentialTargetPolicy表达的 scheme/host/port/path/methods 白名单、redacted_metadata。CredentialSession绑定到具体invocation_id、capability_id、extension_id、account_id的一次调用会话带expires_at与max_uses。CredentialSessionId是刻意不实现Serialize的类 bearer 标识符其Display输出[REDACTED]避免format!({id})、tracing::info!(%id)或错误字符串把可复用的会话凭证泄漏到日志里只有存储路径可通过 crate 私有的to_private_storage_string()拿到原始 UUIDlib.rs。会话生命周期在InMemoryCredentialBroker中被封装进单一锁SessionStatesessions 主表 JIT 铸造索引 placeholder 索引避免多锁自死锁。关键策略create_session会对expires_at默认化并封顶None变为默认 30 分钟CREDENTIAL_SESSION_DEFAULT_TTL_SECONDS任何超过 30 分钟上限的请求CREDENTIAL_SESSION_MAX_TTL_SECONDS都被钳制——无期限永远不会真正被授予显式 revoke 是主要终止手段这个上限只是泄漏/悬挂租约的后备。会话校验validate_session/consume_session_use惰性检查过期与max_uses用量consume_session_use递增用量计数。JIT 铸造路径mint_on_first_use位于 placeholder.rs支持同一 dispatch 内复用已铸造会话CredentialSessionLease带租约计数最后一个租约释放时才会真正撤销会话。6. 运行时 HTTP 出口注入经过审批的注入计划 失败关闭契约的 §4 后半部分描述了共享 Reborn 运行时 HTTP egress 服务如何使用本 crate 的表面检查元数据判断必需的/可选的凭证句柄创建以请求为作用域的一次性租约在宿主进程内恰好一次消费租约在网路调度前拒绝运行时提供的敏感头、类 auth 头、凭证型查询参数、凭证型请求内容、凭证型原始或 percent-decoded URL 内容把材料注入出站请求形状从运行时可见的网络错误与响应头/响应体中擦除租约值剥离敏感响应头并阻止凭证型响应体到达运行时调用方支持 header、query-parameter、path-placeholder、JSON-body、host 组装的 Basic 授权与 VAPID 授权共六类凭证注入目标。两个重要的安全判定Path-placeholder 注入是六类目标中最弱的上游访问日志、CDN/代理日志、崩溃转储与Referer值通常会保留 URL 路径因此它只允许用于有文档化上游要求、无法用 header 或 query param的能力。宿主 egress 将其限制为HTTPS-only拒绝空值、./..、控制字符与保留字符并要求恰好一个完整段占位符使密钥材料无法改写目标路径结构。RuntimeCredentialInjection是 authority-bearing 的、必须宿主派生它不是 guest 代码、运行时代码或扩展进程提交的权限请求。上游 capability/obligation owner 必须证明扩展/能力声明了该密钥句柄、调用方被授权或批准使用、目标 URL 符合能力/密钥目标策略、注入目标与前缀宿主批准、最终请求仍通过网络策略边界。egress 服务不做这个授权决策——它只消费已经批准的注入计划、执行注入与擦除并在必需凭证不可用时 fail closed。Staged obligation 是生产环境的规范直接注入边界生产运行时工具 egress 使用StagedObligation { capability_id }消费BuiltinObligationHandler已经租用、消费并暂存在RuntimeSecretInjectionStore中的材料。SecretStoreLease只保留给显式命名的 legacy/test 兼容路径生产 egress 会在出站传输前拒绝它。运行时适配器使用 staged 来源时不得独立租用同一句柄HostHttpEgressService在出站传输前用take(scope, capability_id, handle)移除 staged 材料使值在成功、失败或运行时可见错误之后都无法复用。Staged 条目在 store TTL默认五分钟后过期过期材料在插入、take(...)与显式prune_expired(...)时被清除。如果一份已批准请求计划把同一 sourcehandle 注入多个目标egress 只消费/租用一次仅在该请求内复用。运行时调用方不得自行提供Authorization、cookie 或 API-key 风格头这些值必须来自宿主批准的注入计划。WASM 宿主中介 HTTP 组合应优先从 manifest v2 的runtime_credentials派生生产 staged 计划声明识别运行时凭证槽、来源secret_handle或 product-auth 账户提供方、HTTPS audience、必需/可选行为与注入目标授权仍决定该次调用是否允许 staged 材料。product-auth 账户来源先解析到所选账户的访问机密再填充同一个一次性交接 store。WasmStagedRuntimeCredentials的显式构造保留给命名的 legacy/test 组合当凭证只对特定目标有效时应优先使用 exact-url 规则。7. 非目标Non-goals边界之外的事契约明确本切片不实现平台 keychain 集成密钥的托管在 keychain 层这里只是解析主密钥密钥轮换/版本化注意版本化 CAS 原语存在但轮换流程本身不在此切片密钥审计事件上报密钥使用的授权策略密钥使用的审批提示从本 crate 直接注入运行时环境/请求OAuth/token 刷新流程网络策略执行这些应作为独立的 service/composition 切片加入而不把运行时或产品面编排语义搬进本 crate。这也是架构测试层ironclaw_architecture_tests会强制的边界README 提到reborn_dependency_boundaries.rs中的BoundaryRule按名称禁止ironclaw_secrets向上依赖。8. 契约测试把不变量钉死在代码里crate 的测试覆盖见 secret_store_contract.rs 与 boundary_contract.rs元数据不返回原始密钥材料secret_store_returns_metadata_without_secret_material一次性租约恰好消费一次secret_store_consumes_one_shot_secret_lease二次消费返回is_consumed()消费一个租约不删除底层机密consuming_one_lease_does_not_delete_underlying_secret可再租再消费同句柄机密在 tenant/user/agent/project 之间隔离跨作用域消费返回is_unknown_lease()并发put_if_absent恰好一个胜者delete幂等且作用域隔离已消费/已撤销的租约记录丢弃保留的密钥材料已撤销租约不能消费缺失机密失败且不创建租约持久化文件系统 store 使原始密钥、凭证账户与凭证会话载荷在静止时加密文件系统 broker 记录保留 tenant/user/agent/project 作用域隔离与会话用量上限畸形或缺失主密钥在组合层报告就绪之前失败crate 边界保持低层不依赖 workflow/runtime/observability crate。运行方式cargo test -p ironclaw_secrets cargo test -p ironclaw_architecture_tests # 边界规则9. 现状与后续Reborn #3088 closeout本契约是 secrets 侧 #3088 的现状权威来源与 #3068凭证注入一致性、#3085共享运行时 HTTP egress、#3026生产组合、#3032无暴露保障并列。本切片已关闭的项目包括libSQL/Postgres 支撑的RootFilesystem上的持久化加密机密存储、经CredentialBroker的持久化凭证账户/会话存储、凭证账户/会话 store 的生产接线护栏、staged-obligation 生产 egress 作为规范直接注入边界、六类 HTTP 凭证注入目标覆盖。明确推迟到 V1 之外的有非 HTTP 凭证、任意脚本或外部 MCP 进程的环境网络凭证注入、外部代理/sidecar 凭证强制、provider 专属 OAuth 刷新 UX、重定向跟随的凭证再注入当前内置宿主 HTTP 返回重定向响应而不跟随因此凭证不会跨跳转发。参考与延伸阅读契约原文docs/internal/reborn/contracts/secrets.md依赖的上游契约docs/internal/reborn/contracts/host-api.md核心实现crates/substrates/ironclaw_secrets/src/secret_store.rs、crates/substrates/ironclaw_secrets/src/lib.rs加密与主密钥crates/substrates/ironclaw_secrets/src/crypto.rs、crates/substrates/ironclaw_secrets/src/keychain.rs契约测试crates/substrates/ironclaw_secrets/tests/secret_store_contract.rs、crates/substrates/ironclaw_secrets/tests/boundary_contract.rscrate 概览crates/substrates/ironclaw_secrets/README.md赞分享人工智能AI 应用交互助手AI Agent【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址https://gitcode.com/gh_mirrors/iro/ironclaw点击查看免费下载相关推荐IronClaw Reborn 记忆契约多租户记忆作用域模型、服务拆分与索引管道实战指南IronClaw Reborn 记忆契约多租户记忆作用域模型、服务拆分与索引管道实战指南 本文以 IronClaw 仓库中的记忆服务合同文档 memory.m人工智能AI 应用交互助手AI AgentIronClaw 密钥服务ironclaw_secrets深度解析一次性租约、凭据经纪与主密钥保护IronClaw 密钥服务ironclaw_secrets深度解析一次性租约、凭据经纪与主密钥保护 导读 ironclaw_secrets 是 IronC人工智能AI 应用交互助手AI AgentIronClaw Reborn 存储放置契约Storage Placement深度解析持久化状态的归属、作用域与验收规则IronClaw Reborn 存储放置契约Storage Placement深度解析持久化状态的归属、作用域与验收规则 本文基于 docs/intern人工智能AI 应用交互助手AI Agent上一篇Go-File与PicGo集成教程打造Markdown写作的完美图片工作流下一篇Rsbuild性能基准测试为什么它比传统构建工具快3倍创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

sshuttle 平台专项指南:TPROXY 完整 IPv6/UDP 支持与 Windows 环境下的 VM 桥接方案
sshuttle 平台专项指南:TPROXY 完整 IPv6/UDP 支持与 Windows 环境下的 VM 桥接方案

网络CLI 【免费下载链接】sshuttle Wrong project! You should head over to http://github.com/sshuttle/sshuttle 项目地址: https://gitcode.com/gh_mirrors/ssh/sshuttle 点击查看 免费下载 导读 本文聚焦 sshuttle 官方文档「Platform Specific Notes」章节&… · 2026/9/25 5:16:12

2024电赛H题小车方案复盘:MSPM0+陀螺仪融合控制实战
2024电赛H题小车方案复盘:MSPM0+陀螺仪融合控制实战

做2024年电赛H题的这段经历,到现在我回想起来,最值钱的不是那块省一的奖状,而是把“MSPM0 陀螺仪融合控制”这套方案从一团乱麻里真正跑通的那几天。H题“自动行驶小车”,听名字好像就是“小车跑起来”,但真上手你会发… · 2026/9/25 5:16:06

STM32烧录三文件解析:.elf/.hex/.bin原理与工程实践
STM32烧录三文件解析:.elf/.hex/.bin原理与工程实践

1. 为什么STM32开发者总在“烧写失败”和“文件格式混乱”之间反复横跳?我第一次用STM32CubeIDE烧写程序时,花了整整一个下午——不是因为代码写错了,而是因为搞不清手里的project.elf、project.hex、project.bin到底该交给谁、怎么交、交了之… · 2026/9/25 5:16:06

ESPnet OWSM-CTC v4 演示应用:一个“页面不在这里“的 1B 编码器语音模型 Gradio Demo 解析
ESPnet OWSM-CTC v4 演示应用:一个“页面不在这里“的 1B 编码器语音模型 Gradio Demo 解析

人工智能语音音频深度学习NLP 【免费下载链接】espnet End-to-End Speech Processing Toolkit 项目地址: https://gitcode.com/gh_mirrors/es/espnet 点击查看 免费下载 本文为 ESPnet 仓库中 egs2/owsm_ctc_v4/s2t1/demo/ 目录(即 Hugging Face Space … · 2026/9/25 5:48:50

Atlas 300V 24G推理卡部署YOLO:从ONNX到OM的完整实践
Atlas 300V 24G推理卡部署YOLO:从ONNX到OM的完整实践

1. 先搞清楚这张卡的真实身份很多人一看到“Atlas 300V 24G”这个型号,第一反应就是:这到底是一张什么卡?是不是运算加速卡?它和游戏显卡、专业图形卡有什么区别?我能不能直接拿来跑YOLO?答案很直接&#x… · 2026/9/25 5:48:50

MediaGo 下载引擎 HTTP API 全解:接口参考、SSE 事件订阅与媒体发现实战
MediaGo 下载引擎 HTTP API 全解:接口参考、SSE 事件订阅与媒体发现实战

音视频桌面应用后端 【免费下载链接】mediago 跨平台视频提取工具:支持流媒体下载、视频下载、m3u8 下载及 B站视频下载,提供 Windows 和 Mac 桌面客户端。Cross-platform video extraction tool: Supports streaming download, video download, m3u8 do… · 2026/9/25 5:48:50

Kata Containers 4.0 架构深度解析:基于 Rust 的异步单进程运行时
Kata Containers 4.0 架构深度解析:基于 Rust 的异步单进程运行时

云原生容器运行时 【免费下载链接】kata-containers Kata Containers is an open source project and community working to build a standard implementation of lightweight Virtual Machines (VMs) that feel and perform like containers, but provide the workload isolat… · 2026/9/25 5:48:44

gridstack.js Angular 集成:GridstackItemComponent 网格项组件完全指南
gridstack.js Angular 集成:GridstackItemComponent 网格项组件完全指南

前端UI组件 【免费下载链接】gridstack.js Build interactive dashboards in minutes. 项目地址: https://gitcode.com/gh_mirrors/gr/gridstack.js 点击查看 免费下载 本文以 angular/doc/api/gridstack-item.component.md 为骨架,结合 gridstack-item… · 2026/9/25 5:48:44

react-map-gl ScaleControl 详解:在 React 中管理地图比例尺控件的声明式方案
react-map-gl ScaleControl 详解:在 React 中管理地图比例尺控件的声明式方案

前端UI组件 【免费下载链接】react-map-gl React friendly API wrapper around MapboxGL JS 项目地址: https://gitcode.com/gh_mirrors/re/react-map-gl 点击查看 免费下载 ScaleControl 是 react-map-gl 对 Mapbox GL JS 原生 ScaleControl 类的 React 封装&… · 2026/9/25 5:48:44

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码