Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
7685e84
confidential workflows e2e
vreff Aug 12, 2026
838ddf0
ci fix
vreff Aug 12, 2026
48a9fd7
fix test
vreff Aug 12, 2026
bcb8fec
fix tests
vreff Aug 12, 2026
273400b
fix tests
vreff Aug 12, 2026
81d9207
fix tests
vreff Aug 12, 2026
a5241c5
update docs
vreff Aug 12, 2026
fc007ba
fix tests
vreff Aug 12, 2026
d83822a
fix tests
vreff Aug 12, 2026
230ae4b
fix test
vreff Aug 12, 2026
e3798b5
consoldiate CI
vreff Aug 12, 2026
95caf43
test updates
vreff Aug 12, 2026
ed40599
fix tests
vreff Aug 12, 2026
cbe23eb
remove envar overrides
vreff Aug 12, 2026
864469b
remove replace
vreff Aug 12, 2026
2c76b23
update docs
vreff Aug 12, 2026
b7f37b4
fix test
vreff Aug 13, 2026
3caa042
lint
vreff Aug 13, 2026
60e5249
fix tests
vreff Aug 13, 2026
0fd5e7e
Update system-tests/tests/smoke/cre/confidential_workflows_test.go
vreff Aug 18, 2026
25f22a3
Skip for lack of envar
vreff Aug 18, 2026
14e257f
Merge branch 'conf-e2e' of https://github.com/smartcontractkit/chainl…
vreff Aug 18, 2026
8360703
move comment
vreff Aug 18, 2026
d6ddce0
make function private
vreff Aug 18, 2026
7f312e0
remove helper func
vreff Aug 18, 2026
7e75d30
Merge branch 'develop' into conf-e2e
vreff Aug 18, 2026
f4911b6
fix md
vreff Aug 18, 2026
0bcef34
Update system-tests/tests/smoke/cre/confidential_workflows_test_helpe…
vreff Aug 18, 2026
d98207f
Merge remote-tracking branch 'origin' into conf-e2e
vreff Aug 18, 2026
e1bee28
Update system-tests/lib/cre/registry_update.go
vreff Aug 18, 2026
d305f34
fix insecure slice
vreff Aug 18, 2026
4efdb85
Merge branch 'conf-e2e' of https://github.com/smartcontractkit/chainl…
vreff Aug 18, 2026
84c1ec4
lint fixes
vreff Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/cre-system-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ jobs:
],
"Test_CRE_V2_HTTP_Action_Multi_Gateway": [
{"topology":"workflow-gateway-capabilities-multi-gateway","configs":"configs/workflow-gateway-capabilities-multi-gateway-don.toml"}
],
"Test_CRE_V2_ConfidentialWorkflows_Relay": [
{"topology":"workflow-gateway-capabilities-confidential-workflows","configs":"configs/workflow-gateway-capabilities-don-confidential-workflows.toml"}
]
}'

Expand Down Expand Up @@ -326,6 +329,49 @@ jobs:
done
exit 1

# The confidential compute relay leg needs a chainlink-confidential-compute
# checkout: the CRE nodes run its confidential-http capability binary, and
# the test drives its enclave harness (tests/testhelpers) to start local
# enclaves. These runners are not Nitro-capable, so the harness falls back
# to fake enclaves (local processes over loopback vsock emulation).
# The confidential-workflows *capability* binary ships in the node image via
# plugins/plugins.public.yaml. The *enclave* side is not a plugin: the test
# drives chainlink-confidential-compute's enclave harness, which shells out
# to that repo's fake-enclave runner. Check it out at the same revision the
# plugin is built from so the capability and the enclave app always match.
Comment on lines +340 to +341

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth making sure that the two revisions never diverge? Could read it from system-tests/tests/go.mod instead of what is listed as the public plugin.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to use the public plugin sha to build the capability binary, because that is what actually gets used in the chainlink node. The revision used in system-tests/tests/go.mod is what consumes the testhelpers/harness, which is a different go module and is used for a different purpose.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do they not have to match?

- name: Resolve confidential compute revision
if: ${{ contains(matrix.tests.test_name, 'ConfidentialWorkflows') }}
id: cc-rev
shell: bash
run: |
set -euo pipefail
ref=$(yq -r '.plugins."confidential-workflows"[0].gitRef' plugins/plugins.public.yaml)
if [ -z "$ref" ] || [ "$ref" = "null" ]; then
echo "could not resolve confidential-workflows gitRef from plugins/plugins.public.yaml" >&2
exit 1
fi
echo "Resolved confidential compute revision: $ref"
echo "ref=$ref" >> "${GITHUB_OUTPUT}"

- name: Checkout chainlink-confidential-compute
if: ${{ contains(matrix.tests.test_name, 'ConfidentialWorkflows') }}
uses: actions/checkout@v7
with:
repository: smartcontractkit/chainlink-confidential-compute
ref: ${{ steps.cc-rev.outputs.ref }}
path: chainlink-confidential-compute
persist-credentials: false

# Prebuild the enclave app and host binaries the fake-enclave runner
# executes, so the cost lands here rather than in the test's own timeout.
# confidential-workflows is its own Go module, so this has to build from
# inside it rather than from the repository root.
- name: Prebuild fake enclave binaries
if: ${{ contains(matrix.tests.test_name, 'ConfidentialWorkflows') }}
shell: bash
working-directory: chainlink-confidential-compute/enclave/apps/confidential-workflows
run: go build ./environments/fake/...

- name: Start local CRE${{ matrix.tests.cre_version }}
id: start-local-cre
uses: ./.github/actions/start-local-cre-environment
Expand All @@ -337,6 +383,9 @@ jobs:
chip-router-image: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{
secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.1"
ctf-configs: ${{ matrix.tests.configs }}
# The confidential workflows test starts enclaves on the harness's
# default ports; the gateway needs them allowlisted to reach them.
env-start-extra-args: ${{ contains(matrix.tests.test_name, 'ConfidentialWorkflows') && '-e 8080,8081,8082,8083' || '' }}
retry-count: "3"
retry-delay-seconds: "15"
cleanup-on-error: "false"
Expand All @@ -362,6 +411,7 @@ jobs:
TEST_TIMEOUT: 7m # let's leave 3 minutes for other steps (the whole job times out after 10 minutes)
RUN_QUARANTINED_TESTS: "true" # always run quarantined tests in CI
TOPOLOGY_NAME: ${{ matrix.tests.topology }}
CONFIDENTIAL_COMPUTE_ROOT: ${{ github.workspace }}/chainlink-confidential-compute
GITHUB_TOKEN: ${{ steps.github-token.outputs.access-token || '' }} # to avoid rate limiting when downloading protobuf files from GitHub
PARALLEL_COUNT: "10"
CRE_TEST_PARALLEL_ENABLED: "true"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# Topology for the confidential workflows engine E2E test.
#
# Differences from workflow-gateway-capabilities-don.toml:
# - the workflow DON also hosts "confidential-workflows" (the capability that
# routes execution into the enclaves) and "confidential-relay" (the gateway
# handler the enclaves call back through)
# - PerWorkflow.ConfidentialWorkflows is enabled so the engine will honour a
# workflow registered with {"confidential":true} attributes
# - the workflow DON exposes remote capabilities and enables the DKG recipient
# so the pre-enclave secret fetch can reach the vault DON
#
# The confidential-workflows capability binary is not part of this repository; it
# is built from a chainlink-confidential-compute checkout and mounted at
# ./binaries/confidential-workflows (see .github/workflows/cre-system-tests.yaml).

# Fake enclaves emit a sentinel attestation document rather than real PCRs, so
# attestation validation is relaxed. INSECURE; for tests only.
[capability_configs.confidential-relay]
[capability_configs.confidential-relay.values]
trustEnclaves = true
requireBFTQuorum = true

# The "enclaves" value is a JSON array of enclaves the capability routes to.
# Whoever starts the enclaves supplies it, since their addresses are only known
# once they are running; absent it, the capability registers an empty list.
[capability_configs.confidential-workflows]
binary_name = "confidential-workflows"
[capability_configs.confidential-workflows.values]
version = "1.0.0-alpha"

[chip_router]
image = "local-cre-chip-router:v1.0.1"

[[blockchains]]
type = "anvil"
chain_id = "1337"
container_name = "anvil-1337"
docker_cmd_params = ["-b", "0.5", "--mixed-mining"]

[[blockchains]]
type = "anvil"
chain_id = "2337"
container_name = "anvil-2337"
port = "8546"
docker_cmd_params = ["-b", "0.5", "--mixed-mining"]

[jd]
csa_encryption_key = "d1093c0060d50a3c89c189b2e485da5a3ce57f3dcb38ab7e2c0d5f0bb2314a44" # any random 32 byte hex string
image = "job-distributor:0.28.0"

[fake]
port = 8171

[fake_http]
port = 8666

[infra]
# either "docker" or "kubernetes"
type = "docker"

[[nodesets]]
nodes = 4
name = "workflow"
don_family = "test-don-family"
don_types = ["workflow"]
override_mode = "all"
http_port_range_start = 10100

supported_evm_chains = [1337, 2337]

env_vars = { CL_EVM_CMD = "", OTEL_SERVICE_NAME = "chainlink-node", CL_CRE_SETTINGS = '{"global":{"VaultOrgIdAsSecretOwnerEnabled":false}}', CL_CRE_SETTINGS_DEFAULT = '{"RemoteExecutableWorkflowDONBindingEnabled":"true","PerWorkflow":{"ConfidentialWorkflows":{"Enabled":"true"}}}' }
capabilities = ["consensus", "confidential-workflows", "confidential-relay", "cron", "http-action", "http-trigger", "don-time", "evm-1337"]
exposes_remote_capabilities = true
registry_based_launch_allowlist = ["cron-trigger@1.0.0"]

[nodesets.db]
image = "postgres:12.0"
port = 13000

[[nodesets.node_specs]]
roles = ["plugin"]
[nodesets.node_specs.node]
docker_ctx = "../../../.."
docker_file = "core/chainlink.Dockerfile"
docker_build_args = { "CL_IS_PROD_BUILD" = "false" }
user_config_overrides = """
[P2P]
EnableExperimentalRageP2P = true

[CRE]
EnableDKGRecipient = true

# The test copies the workflow binary and config into the containers, so the
# syncer reads them from disk rather than fetching them remotely.
[CRE.WorkflowFetcher]
URL = "file:///home/chainlink/workflows"
"""

[[nodesets]]
nodes = 4
name = "capabilities"
don_family = "test-don-family"
don_types = ["capabilities"]
exposes_remote_capabilities = true
override_mode = "all"
http_port_range_start = 10200

supported_evm_chains = [1337, 2337]

env_vars = { CL_EVM_CMD = "", OTEL_SERVICE_NAME = "chainlink-node", CL_CRE_SETTINGS = '{"global":{"VaultOrgIdAsSecretOwnerEnabled":false}}', CL_CRE_SETTINGS_DEFAULT = '{"RemoteExecutableWorkflowDONBindingEnabled":"true"}' }
capabilities = ["vault", "evm-2337"]

[nodesets.db]
image = "postgres:12.0"
port = 13100

[[nodesets.node_specs]]
roles = ["plugin"]
[nodesets.node_specs.node]
docker_ctx = "../../../.."
docker_file = "core/chainlink.Dockerfile"
docker_build_args = { "CL_IS_PROD_BUILD" = "false" }
user_config_overrides = """
[P2P]
EnableExperimentalRageP2P = true

[CRE]
EnableDKGRecipient = true
"""

[[nodesets]]
nodes = 1
name = "bootstrap-gateway"
don_family = "test-don-family"
don_types = ["bootstrap", "gateway"]
override_mode = "each"
http_port_range_start = 10300

env_vars = { CL_EVM_CMD = "", OTEL_SERVICE_NAME = "chainlink-node", CL_CRE_SETTINGS = '{"global":{"PerOrg":{"BaseTriggerRetransmitEnabled":"true"}}}' }
supported_evm_chains = [1337, 2337]

[nodesets.db]
image = "postgres:12.0"
port = 13200

[[nodesets.node_specs]]
roles = ["bootstrap", "gateway"]
[nodesets.node_specs.node]
docker_ctx = "../../../.."
docker_file = "core/chainlink.Dockerfile"
# 5002 is the web API capabilities port for incoming requests
# 15002 is the vault port for incoming requests
custom_ports = ["5002:5002","15002:15002"]
user_config_overrides = ""
30 changes: 18 additions & 12 deletions core/scripts/cre/environment/environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,18 +363,7 @@ func startCmd() *cobra.Command {
}

features := feature_set.New()
extraAllowedPorts := append([]int(nil), extraAllowedGatewayPorts...)
if in.Fake != nil {
extraAllowedPorts = append(extraAllowedPorts, in.Fake.Port)
}
if in.FakeHTTP != nil {
extraAllowedPorts = append(extraAllowedPorts, in.FakeHTTP.Port)
}

gatewayWhitelistConfig := gateway.WhitelistConfig{
ExtraAllowedPorts: extraAllowedPorts,
ExtraAllowedIPsCIDR: []string{"0.0.0.0/0"},
}
gatewayWhitelistConfig := defaultGatewayWhitelistConfig(in, extraAllowedGatewayPorts)
output, startErr := StartCLIEnvironment(cmdContext, relativePathToRepoRoot, in, nil, features, nil, envDependencies, gatewayWhitelistConfig)
if startErr != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", startErr)
Expand Down Expand Up @@ -855,6 +844,23 @@ func statusCmd() *cobra.Command {
return cmd
}

// defaultGatewayWhitelistConfig builds the Gateway Connector's outbound allowlist:
// the caller's extra ports plus the fake service ports the config declares.
func defaultGatewayWhitelistConfig(in *envconfig.Config, extraAllowedPorts []int) gateway.WhitelistConfig {
ports := append([]int(nil), extraAllowedPorts...)
if in.Fake != nil {
ports = append(ports, in.Fake.Port)
}
if in.FakeHTTP != nil {
ports = append(ports, in.FakeHTTP.Port)
}

return gateway.WhitelistConfig{
ExtraAllowedPorts: ports,
ExtraAllowedIPsCIDR: []string{"0.0.0.0/0"},
}
}

func StartCLIEnvironment(
cmdContext context.Context,
relativePathToRepoRoot string,
Expand Down
1 change: 1 addition & 0 deletions core/scripts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ require (
github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260624154507-ea7ff77a0ddb // indirect
github.com/smartcontractkit/chainlink-ccv v0.1.1-0.20260716164331-d938b371c5d6 // indirect
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20260724142814-45996a1bcb72 // indirect
github.com/smartcontractkit/chainlink-confidential-compute v1.3.0 // indirect
github.com/smartcontractkit/chainlink-data-streams v1.1.0 // indirect
github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260403151002-2c91155b5501 // indirect
github.com/smartcontractkit/chainlink-feeds v0.1.2-0.20250227211209-7cd000095135 // indirect
Expand Down
2 changes: 2 additions & 0 deletions core/scripts/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion go.md
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,10 @@ flowchart LR
click chainlink-common/pkg/values href "https://github.com/smartcontractkit/chainlink-common"
chainlink-common/pkg/workflows/sdk/v2/pb --> chainlink-common/pkg/values
click chainlink-common/pkg/workflows/sdk/v2/pb href "https://github.com/smartcontractkit/chainlink-common"
chainlink-confidential-compute --> tdh2/go/tdh2
click chainlink-confidential-compute href "https://github.com/smartcontractkit/chainlink-confidential-compute"
chainlink-confidential-compute/tests/testhelpers --> chainlink-confidential-compute
click chainlink-confidential-compute/tests/testhelpers href "https://github.com/smartcontractkit/chainlink-confidential-compute"
chainlink-data-streams --> chainlink-common/keystore
chainlink-data-streams --> chainlink-evm/gethwrappers
click chainlink-data-streams href "https://github.com/smartcontractkit/chainlink-data-streams"
Expand Down Expand Up @@ -503,10 +507,12 @@ flowchart LR
chainlink/load-tests --> chainlink-testing-framework/havoc
chainlink/load-tests --> chainlink/integration-tests
click chainlink/load-tests href "https://github.com/smartcontractkit/chainlink"
chainlink/system-tests/lib --> chainlink-confidential-compute
chainlink/system-tests/lib --> chainlink-testing-framework/framework/components/chiprouter
chainlink/system-tests/lib --> chainlink-testing-framework/framework/components/dockercompose
chainlink/system-tests/lib --> chainlink-testing-framework/framework/components/fake
click chainlink/system-tests/lib href "https://github.com/smartcontractkit/chainlink"
chainlink/system-tests/tests --> chainlink-confidential-compute/tests/testhelpers
chainlink/system-tests/tests --> chainlink/core/scripts/cre/environment/examples/workflows/cron
chainlink/system-tests/tests --> chainlink/core/scripts/cre/environment/examples/workflows/proof-of-reserve/cron-based
chainlink/system-tests/tests --> chainlink/system-tests/lib
Expand Down Expand Up @@ -710,6 +716,12 @@ flowchart LR
end
click chainlink-common-repo href "https://github.com/smartcontractkit/chainlink-common"

subgraph chainlink-confidential-compute-repo[chainlink-confidential-compute]
chainlink-confidential-compute
chainlink-confidential-compute/tests/testhelpers
end
click chainlink-confidential-compute-repo href "https://github.com/smartcontractkit/chainlink-confidential-compute"

subgraph chainlink-evm-repo[chainlink-evm]
chainlink-evm
chainlink-evm/contracts/cre/gobindings
Expand Down Expand Up @@ -806,5 +818,5 @@ flowchart LR
click testrig-repo href "https://github.com/smartcontractkit/testrig"

classDef outline stroke-dasharray:6,fill:none;
class chainlink-repo,chainlink-aptos-repo,chainlink-ccip-repo,chainlink-ccv-repo,chainlink-common-repo,chainlink-evm-repo,chainlink-framework-repo,chainlink-protos-repo,chainlink-solana-repo,chainlink-stellar-repo,chainlink-sui-repo,chainlink-testing-framework-repo,chainlink-ton-repo,cre-sdk-go-repo,testrig-repo outline
class chainlink-repo,chainlink-aptos-repo,chainlink-ccip-repo,chainlink-ccv-repo,chainlink-common-repo,chainlink-confidential-compute-repo,chainlink-evm-repo,chainlink-framework-repo,chainlink-protos-repo,chainlink-solana-repo,chainlink-stellar-repo,chainlink-sui-repo,chainlink-testing-framework-repo,chainlink-ton-repo,cre-sdk-go-repo,testrig-repo outline
```
Loading
Loading