Skip to content

Commit

Permalink
Merge pull request #5975 from oasisprotocol/peternose/trivial/simplif…
Browse files Browse the repository at this point in the history
…y-create-provisioner

go/runtime/registry: Simplify creation of provisioners
  • Loading branch information
peternose authored Jan 10, 2025
2 parents 4aa7157 + 00d4b91 commit c9acbf2
Show file tree
Hide file tree
Showing 14 changed files with 195 additions and 99 deletions.
2 changes: 1 addition & 1 deletion .buildkite/code.pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ steps:
- .buildkite/scripts/test_e2e.sh --timeout 20m --scenario e2e/runtime/runtime-encryption
env:
OASIS_TEE_HARDWARE: intel-sgx
OASIS_UNSAFE_MOCK_SGX: "1"
OASIS_UNSAFE_MOCK_TEE: "1"
OASIS_UNSAFE_SKIP_AVR_VERIFY: "1"
OASIS_E2E_COVERAGE: enable
TEST_BASE_DIR: /tmp
Expand Down
47 changes: 47 additions & 0 deletions .changelog/5975.cfg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
go/runtime/config: Support selection of TEE kind

The node operator can now specify the kind of Trusted Execution Environment
(TEE) in which the runtime component should run. If no TEE is specified,
it is automatically selected, with TDX and SGX taking precedence over ELF.

The following configuration option has been deprecated:

- `runtime.environment`

The following configuration options have been added:

- `runtime.debug_mock_tee` to enable TEE mocking for testing,

- `runtime.runtimes.components.tee` to specify the TEE for a component.

These changes affect the configuration of the client node if the runtime
bundle contains both TEE and non-TEE binaries. In such cases, the node
operator must explicitly configure the runtime to avoid running in a TEE
environment.

Configuring non-TEE Paratime Client Node:

```
mode: client
# ... sections not relevant are omitted ...
runtime:
paths:
- {{ runtime_orc_path }}
runtimes:
- id: {{ runtime_id }}
components:
- id: ronl
tee: none # Don't run in SGX or TDX!
```

Configuring TEE Paratime Client Node:

```
mode: client
# ... sections not relevant are omitted ...
runtime:
paths:
- {{ runtime_orc_path }}
sgx_loader: /node/bin/oasis-core-runtime-loader
# environment: sgx # Deprecated, can be removed.
```
3 changes: 3 additions & 0 deletions .changelog/5975.internal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
go/oasis-test-runner: Generalize OASIS_UNSAFE_MOCK_SGX flag

Flag OASIS_UNSAFE_MOCK_SGX was renamed to OASIS_UNSAFE_MOCK_TEE.
4 changes: 2 additions & 2 deletions common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,8 @@ endif
# https://goreleaser.com/customization/build/#define-build-tag
export GORELEASER_CURRENT_TAG := $(RELEASE_TAG)

# If mock SGX is configured, define extra runtime build flags.
ifdef OASIS_UNSAFE_MOCK_SGX
# If mock TEE is configured, define extra runtime build flags.
ifdef OASIS_UNSAFE_MOCK_TEE
OASIS_RUNTIME_NONSGX_FLAGS := --features debug-mock-sgx
else
OASIS_RUNTIME_NONSGX_FLAGS :=
Expand Down
5 changes: 2 additions & 3 deletions go/oasis-test-runner/oasis/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import (
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/log"
"github.com/oasisprotocol/oasis-core/go/oasis-test-runner/oasis/cli"
roothash "github.com/oasisprotocol/oasis-core/go/roothash/api"
runtimeConfig "github.com/oasisprotocol/oasis-core/go/runtime/config"
scheduler "github.com/oasisprotocol/oasis-core/go/scheduler/api"
staking "github.com/oasisprotocol/oasis-core/go/staking/api"
)
Expand Down Expand Up @@ -683,8 +682,8 @@ func (net *Network) startOasisNode(
if os.Getenv("OASIS_UNSAFE_LAX_AVR_VERIFY") != "" {
extraArgs = extraArgs.debugTCBLaxVerify()
}
if os.Getenv("OASIS_UNSAFE_MOCK_SGX") != "" {
cfg.Runtime.Environment = runtimeConfig.RuntimeEnvironmentSGXMock
if os.Getenv("OASIS_UNSAFE_MOCK_TEE") != "" {
cfg.Runtime.DebugMockTEE = true
}
} else {
baseArgs = append(baseArgs, "--"+cmdFlags.CfgGenesisFile, net.GenesisPath())
Expand Down
9 changes: 4 additions & 5 deletions go/runtime/bundle/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (
type ExplodedComponent struct {
*Component

// TEEKind specifies the kind of Trusted Execution Environment (TEE)
// in which the component should run.
TEEKind component.TEEKind

// Detached is true iff the bundle containing the component does not
// include a RONL component.
Detached bool
Expand Down Expand Up @@ -132,11 +136,6 @@ func (c *Component) IsNetworkAllowed() bool {
}
}

// IsTEERequired returns true iff the component only provides TEE executables.
func (c *Component) IsTEERequired() bool {
return c.Executable == "" && c.ELF == nil && c.TEEKind() != component.TEEKindNone
}

// TEEKind returns the kind of TEE supported by the component.
func (c *Component) TEEKind() component.TEEKind {
switch {
Expand Down
18 changes: 18 additions & 0 deletions go/runtime/bundle/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/oasisprotocol/oasis-core/go/config"
cmdFlags "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common/flags"
"github.com/oasisprotocol/oasis-core/go/runtime/bundle/component"
rtConfig "github.com/oasisprotocol/oasis-core/go/runtime/config"
)

// CfgDebugMockIDs configures mock runtime IDs for the purpose of testing.
Expand Down Expand Up @@ -153,6 +154,22 @@ func (r *registry) AddBundle(path string, manifestHash hash.Hash) error {

// Add components to the registry.
for compID, comp := range components {
teeKind := comp.TEEKind()
if compCfg, ok := config.GlobalConfig.Runtime.GetComponent(bnd.Manifest.ID, compID); ok {
if kind, ok := compCfg.TEEKind(); ok {
teeKind = kind
}
} else {
// Support legacy configuration where the runtime environment determines
// whether the client node should run the runtime in an SGX environment.
isEnvAuto := config.GlobalConfig.Runtime.Environment == rtConfig.RuntimeEnvironmentAuto
hasSGXLoader := config.GlobalConfig.Runtime.SGXLoader != ""
insecureMock := config.GlobalConfig.Runtime.DebugMockTEE
if comp.ID().IsRONL() && config.GlobalConfig.Mode.IsClientOnly() && isEnvAuto && !hasSGXLoader && !insecureMock {
teeKind = component.TEEKindNone
}
}

runtimeComponents, ok := r.components[bnd.Manifest.ID]
if !ok {
runtimeComponents = make(map[component.ID]map[version.Version]*ExplodedComponent)
Expand All @@ -167,6 +184,7 @@ func (r *registry) AddBundle(path string, manifestHash hash.Hash) error {

componentVersions[comp.Version] = &ExplodedComponent{
Component: comp,
TEEKind: teeKind,
Detached: detached,
ExplodedDataDir: explodedDataDir,
}
Expand Down
82 changes: 75 additions & 7 deletions go/runtime/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,27 @@ const (
// Use of this runtime environment is only allowed if DebugDontBlameOasis flag is set.
RuntimeEnvironmentSGXMock RuntimeEnvironment = "sgx-mock"

// RuntimeEnvironmentELF specifies to run the runtime in the OS address space.
//
// Use of this runtime environment is only allowed if DebugDontBlameOasis flag is set.
RuntimeEnvironmentELF RuntimeEnvironment = "elf"

// RuntimeEnvironmentAuto specifies to run the runtime in the most appropriate location.
RuntimeEnvironmentAuto RuntimeEnvironment = "auto"
)

// TEESelectMode is the selection mode for the Trusted Execution Environment (TEE).
type TEESelectMode string

const (
// TEESelectModeAuto specifies that the runtime should run in the most appropriate TEE.
TEESelectModeAuto TEESelectMode = ""

// TEESelectModeNone specifies that the runtime should run without using any TEE.
TEESelectModeNone TEESelectMode = "none"

// TEESelectModeSGX specifies that the runtime should run in an SGX environment.
TEESelectModeSGX TEESelectMode = "sgx"

// TEESelectModeTDX specifies that the runtime should run in a TDX environment.
TEESelectModeTDX TEESelectMode = "tdx"
)

// Config is the runtime registry configuration structure.
type Config struct {
// Runtimes is the list of runtimes to configure.
Expand All @@ -84,10 +96,11 @@ type Config struct {
// Path to the sandbox binary (bubblewrap).
SandboxBinary string `yaml:"sandbox_binary,omitempty"`

// Path to SGXS runtime loader binary (for SGX runtimes).
// Path to SGX runtime loader binary (for SGX runtimes).
SGXLoader string `yaml:"sgx_loader,omitempty"`

// The runtime environment (sgx, elf, auto).
// NOTE: This may go away in the future, use `DebugMockTEE` instead.
Environment RuntimeEnvironment `yaml:"environment,omitempty"`

// History pruner configuration.
Expand Down Expand Up @@ -122,6 +135,11 @@ type Config struct {
//
// If not specified, a default value is used.
MaxBundleSize string `yaml:"max_bundle_size,omitempty"`

// DebugMockTEE enables mocking of the Trusted Execution Environment (TEE).
//
// This flag can only be used if the DebugDontBlameOasis flag is set.
DebugMockTEE bool `yaml:"debug_mock_tee,omitempty"`
}

// GetComponent returns the configuration for the given component
Expand Down Expand Up @@ -170,16 +188,61 @@ type RuntimeConfig struct {
Repositories []string `yaml:"repositories,omitempty"`
}

// Validate validates the runtime configuration.
func (c *RuntimeConfig) Validate() error {
for _, comp := range c.Components {
if err := comp.Validate(); err != nil {
return err
}
}
return nil
}

// ComponentConfig is the component configuration.
type ComponentConfig struct {
// ID is the component identifier.
ID component.ID `yaml:"id"`

// TEE specifies the kind of Trusted Execution Environment (TEE)
// in which the component should run (none, sgx, tdx).
//
// If not provided, the TEE kind is selected automatically.
TEE TEESelectMode `yaml:"tee,omitempty"`

// Disabled specifies whether the component is disabled. If a component is specified and not
// disabled, it is enabled.
Disabled bool `yaml:"disabled,omitempty"`
}

// Validate validates the component configuration.
func (c *ComponentConfig) Validate() error {
switch c.TEE {
case TEESelectModeAuto:
case TEESelectModeNone:
case TEESelectModeSGX:
case TEESelectModeTDX:
default:
return fmt.Errorf("unknown TEE select mode: %s", c.TEE)
}

return nil
}

// TEEKind returns the kind of Trusted Execution Environment (TEE)
// in which the component should run, if it is specified.
func (c *ComponentConfig) TEEKind() (component.TEEKind, bool) {
switch c.TEE {
case TEESelectModeNone:
return component.TEEKindNone, true
case TEESelectModeSGX:
return component.TEEKindSGX, true
case TEESelectModeTDX:
return component.TEEKindTDX, true
default:
return 0, false
}
}

// UnmarshalYAML implements yaml.Unmarshaler.
func (c *ComponentConfig) UnmarshalYAML(value *yaml.Node) error {
switch value.ShortTag() {
Expand Down Expand Up @@ -231,7 +294,6 @@ func (c *Config) Validate() error {
return fmt.Errorf("sgx_loader must be set when using sgx environment")
}
case RuntimeEnvironmentSGXMock:
case RuntimeEnvironmentELF:
case RuntimeEnvironmentAuto:
default:
return fmt.Errorf("unknown runtime environment: %s", c.Environment)
Expand All @@ -251,6 +313,12 @@ func (c *Config) Validate() error {
return fmt.Errorf("cannot specify more than 128 instances for load balancing")
}

for _, rt := range c.Runtimes {
if err := rt.Validate(); err != nil {
return err
}
}

return nil
}

Expand Down
4 changes: 2 additions & 2 deletions go/runtime/host/composite/composite.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,9 @@ func (p *provisioner) NewRuntime(cfg host.Config) (host.Runtime, error) {
if comp == nil {
return nil, fmt.Errorf("host/composite: component not available")
}
provisioner, ok := p.kinds[comp.TEEKind()]
provisioner, ok := p.kinds[comp.TEEKind]
if !ok {
return nil, fmt.Errorf("host/composite: provisioner for kind '%s' is not available", comp.TEEKind())
return nil, fmt.Errorf("host/composite: provisioner for kind '%s' is not available", comp.TEEKind)
}
return provisioner.NewRuntime(cfg)
}
Expand Down
2 changes: 1 addition & 1 deletion go/runtime/host/sgx/sgx.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ func (s *sgxProvisioner) getSandboxConfig(rtCfg host.Config, conn sandbox.Connec
return cfg, nil
}

if comp.TEEKind() != component.TEEKindSGX {
if comp.SGX == nil {
return process.Config{}, fmt.Errorf("component '%s' is not an SGX component", comp.ID())
}

Expand Down
2 changes: 1 addition & 1 deletion go/runtime/host/tdx/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (q *qemuProvisioner) getSandboxConfig(rtCfg host.Config, _ sandbox.Connecto
if err != nil {
return process.Config{}, err
}
if comp.TEEKind() != component.TEEKindTDX {
if comp.TDX == nil {
return process.Config{}, fmt.Errorf("component '%s' is not a TDX component", comp.ID())
}

Expand Down
Loading

0 comments on commit c9acbf2

Please sign in to comment.