Defender 即代码插件
Defender 即代码 (DaC) 是一个 Serverless Framework 插件,用于自动化资源管理和配置即代码。
警告: 该插件正在开发中,行为可能会发生变化。谨慎使用。
前提条件
Serverless Framework: 入门
安装
您可以直接使用我们预配置的模板初始化您的 Serverless 项目:
sls install --url https://github.com/OpenZeppelin/defender-as-code/tree/main/template -n my-service
为了使以上命令能够正确运行,您需要有权访问此 repo。 |
或者,您可以直接将其安装到现有项目中:
yarn add @openzeppelin/defender-as-code
设置
您可以通过几种方式设置 serverless.yml
配置:
-
从头开始创建;
-
使用 Defender 的 2.0 Serverless 导出功能;
如果您已经在 Defender 中拥有诸如合约、通知、Relayer、Action 等资源,您可以从管理 → 高级页面导出一个包含这些资源的 serverless.yml
配置文件。

如果您之前使用 defender-as-code 部署到同一帐户,并且随后通过 Defender 用户界面创建了新资源,则导出功能将根据您最新的部署堆栈的名称自动为新资源分配一个 stackResourceId 。如果您以前未使用 defender-as-code 进行部署,则将使用默认堆栈名称 mystack 。
|
此插件允许您从 serverless.yml
中以声明方式定义 Action、Monitor、通知、区块浏览器 API 密钥、Relayer、合约和密钥,并通过 CLI 使用 serverless deploy
来配置它们。以下是一个示例模板,其中定义了一个 Action、一个 Relayer、一个策略和一个 Relayer API 密钥:
service: defender-as-code-template
configValidationMode: error
frameworkVersion: '3'
provider:
name: defender
stage: ${opt:stage, 'dev'}
stackName: 'mystack'
ssot: false
defender:
key: '${env:TEAM_API_KEY}'
secret: '${env:TEAM_API_SECRET}'
resources:
actions:
action-example-1:
name: 'Hello world from serverless'
path: './actions/hello-world'
relayer: ${self:resources.relayers.relayer-1}
trigger:
type: 'schedule'
frequency: 1500
paused: false
# optional - unencrypted and scoped to the individual action
environment-variables:
hello: 'world!'
action-example-2: 2cbc3f58-d962-4be8-a158-1035be4b661c
policies:
policy-1:
gas-price-cap: 1000
whitelist-receivers:
- '0x0f06aB75c7DD497981b75CD82F6566e3a5CAd8f2'
eip1559-pricing: true
relayers:
relayer-1:
name: 'Test Relayer 1'
network: 'sepolia'
min-balance: 1000
policy: ${self:resources.policies.policy-1}
api-keys:
- key1
plugins:
- '@openzeppelin/defender-as-code'
这需要在 YAML 文件的 defender
属性下设置 key
和 secret
。我们建议使用环境变量或安全的(git 忽略的)配置文件来检索这些值。相应地修改 serverless.yml
。
确保 Defender Team API 密钥已配置所有相应的 API 功能。
stackName
(例如 mystack) 与资源键 (例如 relayer-1) 结合使用,以唯一标识每个资源。此标识符称为 stackResourceId
(例如 mystack.relayer-1),允许您在同一租户中管理多个部署。
您还可以通过它们的唯一 ID (例如 2cbc3f58-d962-4be8-a158-1035be4b661c
) 直接引用现有的 Defender 资源。这些资源将不受插件管理,并且在部署过程中将被忽略。但是,您可以在其他资源中引用它们,以相应地更新它们的配置。
以下是支持直接引用的属性列表:
-
relayer
可以在 Action 中引用relayerId
-
action-trigger
可以在 Monitor 中引用actionid
-
action-condition
可以在 Monitor 中引用actionId
-
address-from-relayer
可以在 Relayer 中引用relayerId
-
notify-config.channels
可以在 Monitor 中引用多个notificationId
-
contracts
可以取代addresses
,并在 Monitor 中引用多个contractId
以下示例展示了如何在 Monitor 和 Action 中分别使用对 Defender 合约和 Relayer 的直接引用:
...
contracts:
contract-1: 'sepolia-0xd70d6A0480420b4C788AF91d0E1b0ca6141A9De8' # Defender 中现有资源的 contractId
relayers:
relayer-2: 'bcb659c6-7e11-4d37-a15b-0fa9f3d3442c' # Defender 中现有 Relayer 的 relayerId
actions:
action-example-1:
name: 'Hello world from serverless'
path: './actions/hello-world'
relayer: ${self:resources.relayers.relayer-2}
trigger:
type: 'schedule'
frequency: 1500
paused: false
monitors:
block-example:
name: 'Block Example'
type: 'BLOCK'
network: 'sepolia'
risk-category: 'TECHNICAL'
# optional - either contracts OR addresses should be defined
contracts:
- ${self:resources.contracts.contract-1}
...
...
SSOT 模式
在 serverless.yml
文件中的 provider
属性下,您可以选择添加一个 ssot
布尔值。SSOT 或单一数据源,确保您在 Defender 中的堆栈状态与 serverless.yml
模板完全同步。
这意味着,所有未在您当前模板文件中定义的资源,在部署时都会从 Defender 中删除,Relayer 除外。如果 SSOT 未在模板中定义,它将默认为 false
。
从 serverless.yml
文件中删除的任何资源都_不会_自动删除,以防止意外删除资源。要预期此行为,必须启用 SSOT 模式。
密钥 (Action)
Action 密钥可以全局定义,也可以按堆栈定义。在 global
下定义的密钥不受 stackName
更改的影响,并在新堆栈下重新部署时保留。当堆栈在新 stackName
下重新部署时,在 stack
下定义的密钥将被删除(前提是启用了 SSOT 模式)。要引用在 stack
下定义的密钥,请使用以下格式:<stackname>_<secretkey>
,例如 mystack_test
。
secrets:
# optional - 全局密钥不受 stackName 更改的影响
global:
foo: ${self:custom.config.secrets.foo}
hello: ${self:custom.config.secrets.hello}
# optional - 堆栈密钥(格式为 <stackname>_<secretkey>)
stack:
test: ${self:custom.config.secrets.test}
类型和模式验证
我们提供基于 JSON 模式自动生成的文档:
有关类型的更多信息可以在 此处找到。具体而言,是以 Y
开头的类型(例如 YRelayer)。对于模式,您可以查看 docs-schema 文件夹。
此外,还提供了一个 示例项目,该项目提供了可以在 serverless.yml
文件中定义的大多数属性。
命令
部署
您可以使用 sls deploy
将当前堆栈部署到 Defender。
部署采用一个可选的 --stage
标志,该标志在从以上模板安装时默认为 dev
。
此外,serverless.yml
可能包含一个 ssot
属性。更多信息可以在 SSOT 模式 部分找到。
此命令将在当前工作目录的 .defender
文件夹中附加一个日志条目。此外,如果创建了任何新的 Relayer 密钥,这些密钥将作为 JSON 对象存储在 .defender/relayer-keys
文件夹中。
警告: 从模板安装时,我们确保从任何 git 提交中忽略 .defender
文件夹。但是,当直接安装时,请确保将此文件夹添加到您的 .gitignore
文件中。
移除
您可以使用 sls remove
从 Defender 中删除在 serverless.yml
文件中定义的所有资源。
为了避免潜在的资金损失,只能直接从 Defender UI 中删除 Relayer。 |
注意事项
在 deploy
过程中抛出的错误不会回滚任何先前的更改。常见的错误是:
-
未设置 API 密钥和 secret
-
API 密钥的权限不足
-
serverless.yml
文件的验证错误(请参阅 类型和模式验证)
通常,修复错误并重试部署应该足够了,因为任何现有资源都将属于部署的 update
子句。但是,如果不确定,您可以随时调用 sls remove
来删除整个堆栈,然后重试。
Action 密钥是加密的键值对,并在运行时注入到 lambda 环境中。密钥自动限定于所有 Action。或者,您可以使用 environment-variables 来定义限定于单个 Action 的键值对,并通过 process.env
在运行时可用。请注意,这些值未加密。