安全、secrets 和安全运营

使用 Lino 生成的应用程序,其安全性从生成的项目本身开始。Lino 已经注册本地 secrets,在 Aspire 中配置敏感参数,并为 API 创建 JWT、API keys、临时 tokens 和 rate limiting policies 的基础。

本页说明这些保护为什么存在,以及在应用程序演进时如何保持它们。核心思想是:secret 不应在仓库中产生,public API 也不应在没有使用限制的情况下产生;Lino 提供这种模式,以减少凭据意外泄露,以及 login、refresh token、注册和密码恢复等敏感 endpoints 被滥用的风险。

项目本地 secrets

Lino 会自动注册生成应用所需的本地 secrets。数据库、Redis、RabbitMQ 的密码、JWT 密钥、API keys 以及其他敏感值会保存在应用程序的 User Secrets 中,而不是出现在受版本控制的文件里。

lino secret list
lino secret set
lino secret remove
lino secret clear

这些命令在维护时仍然有用:使用 secret list 审计已配置的键,使用 secret set 修改或注册本地值,使用 secret remove 删除某个键,使用 secret clear 清除项目的所有本地 secrets。

此流程已集成到生成的项目中。当你添加 Redis、RabbitMQ、身份验证、授权、SMTP、API keys 或 download tokens 等资源时,Lino 会让敏感值保持在源代码之外,并让应用程序准备好以环境配置的形式接收它们。

适用时,你也可以使用 .NET 和 Aspire 平台工具检查本地 secrets,例如 dotnet user-secrets list 或等效的 Aspire 资源。Lino 命令的作用,是在生成项目的上下文中让这个流程更直接。

Aspire 中的参数

Aspire AppHost 协调数据库、Redis、RabbitMQ、API、worker 和 web app 等资源。在生成的项目中,Lino 将敏感值注册为 Aspire 参数,使应用程序将这些值视为外部依赖,而不是源代码中的固定数据。

这包括数据库、Redis、RabbitMQ 的密码,以及本地基础设施所需的其他值。AppHost 使用 Aspire 的 secret 模型将这些参数传递给对应资源,例如使用标记为 sensitive 的参数。

实际收益是,secret 不再是散落在配置文件中的细节,而是成为解决方案执行模型的一部分。当你通过 Aspire 运行应用程序时,各服务会收到所需依赖,而不需要你手动把密码复制到每个项目中。

这种设计也有助于 deploy。当 Aspire 发布产物时,对这些参数的需求仍然存在:例如在 Docker Compose 中,可能会出现需要在正确环境中填写的 placeholders 和环境文件;在其他 targets 中,相同原则也指导敏感配置如何传递给平台。

Rate limiting

Rate limiting 可以减少滥用、brute force 和不当资源消耗。Lino 已经配置默认 policies,并在生成的 endpoints 上应用 helpers,使 public、authenticated、internal 和 sensitive API 不会在没有使用限制的情况下创建。

这很重要,因为 API 即使正确完成身份验证,仍可能遭受大量调用滥用。Login、refresh token、注册和密码恢复都是敏感流程;默认情况下,Lino 会将它们与普通 endpoints 分开,使其具有更保守的限制。

  • 创建新 endpoints 时使用生成的 policies。
  • 为敏感 endpoints 和普通 endpoints 保持不同限制。
  • 必要时将 rate limiting 与身份验证、验证和 bot 防护结合使用。
  • 当超过限制时,将 429 Too Many Requests 视为预期响应。
PolicyLino 中的默认用途演进时如何应用
anonymous无需身份验证的 public endpoints。用于不会创建 tokens、accounts 或 credentials 的匿名 API。
authenticated-user按当前用户分区的 authenticated traffic。作为普通 authenticated API 的默认选择。
identity-sensitiveLogin、注册、refresh token、忘记密码以及密码更改/reset。用于创建 tokens、codes 或更改 credentials 的 endpoints。
api-key由 API key 保护的 internal endpoints。用于遵循 API key filter 的 service-to-service 集成。
download-token生成临时 download tokens。当 authenticated users 可以签发短期 links 或 tokens 时使用。

JWT 安全

添加身份验证时,Lino 会生成 JWT 签发、读取和验证的基础,同时让签名密钥保持在源代码之外。token 用于识别用户并携带必要 claims,但不会把 JWT 变成一个可携带的数据库。

  • 开发时将签名密钥保存在 User Secrets 中,生产环境中保存在安全 provider 中。
  • 保留项目中配置的 issuer、audience、过期时间和算法验证。
  • 只包含认证流程所需的 claims。
  • 在 multi-tenancy 中,使用 Lino 已经提供的 user 和 tenant context。

JWT 签名密钥是关键 secret,Lino 已经将该值作为敏感配置处理。创建新环境、pipeline 或 deploy 时,请保持同一规则:密钥不得出现在 commit、Docker image、log、公开文件或真实配置示例中。

JWT 也不能替代领域中的授权。Claims 有助于做出决策,但关键操作仍然需要考虑当前状态、用户状态、有效 permissions 和请求 context。生成的部分提供基础;在系统演进时,你的责任是不创建绕过此流程的捷径。

API keys 和 download tokens

Lino 将 API keys 和临时 tokens 视为有限 scope 的 credentials。当某个流程需要临时开放对文件、包或集成的访问时,生成的基础会优先使用短期且具体的 tokens,而不是复用范围过宽的 credentials。

  • 为 links 和临时 tokens 使用较短的过期时间。
  • 当流程具备相关 context 时,将 token 与 user、tenant 和 resource 关联。
  • 当访问涉及敏感 artefacts 时,记录使用情况以便审计。
  • 当 resource 或 permission 发生变化时,撤销 tokens。

受 key 保护的 API 使用 Lino 生成的授权和 rate limiting 模型。为集成自动化创建的 key 不应成为管理调用的通行证,临时 download token 也不应替代 authenticated user 的 permissions。

创建新的 download 或集成流程时,保持同样的思路:明确 scope、过期时间、有用 metadata 和合适的 rate limiting policy。这样临时访问会保持可审计、可预测,而不是变成在系统中流转的松散 credential。

生产环境中的 secret providers

User Secrets 解决本地开发问题。在生产环境中,请使用平台的安全 provider 保持同样的分离:Azure Key Vault、AWS Secrets Manager、Google Secret Manager、HashiCorp Vault、Kubernetes Secrets,或由 orchestrator 保护的环境变量。

Lino 会让应用程序准备好从代码外部接收敏感配置。切换到生产环境是环境层面的决策:名称和参数会继续存在,但值会开始来自基础设施所使用的 vault、pipeline 或 orchestrator。

生产环境还需要引入 rotation、按环境隔离、按应用授权和访问审计等运维实践。User Secrets 不能替代这些控制;它们覆盖的是本地体验,同时避免把 secrets 放进仓库。

  • 按环境分离:development、staging 和 production 不应共享 credentials。
  • 按应用分离:每个服务只应接收自己需要的 secrets。
  • 规划 rotation:JWT keys、SMTP、API keys 和数据库密码都需要替换流程。
  • 审计访问:记录谁可以在平台中读取或更改 secrets。
发生了未处理的错误。 重新加载 🗙