Skip to content

Commit f2897e6

Browse files
committed
initdata-processor: add insecure field for initdata
1 parent 7367f58 commit f2897e6

3 files changed

Lines changed: 92 additions & 15 deletions

File tree

initdata-processor/main.go

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package main
66
import (
77
"bytes"
88
"context"
9-
"errors"
9+
"encoding/json"
1010
"fmt"
1111
"io"
1212
"io/fs"
@@ -23,8 +23,9 @@ import (
2323
)
2424

2525
const (
26-
measuredConfigPath = "/run/measured-cfg"
27-
insecureConfigPath = "/run/insecure-cfg"
26+
measuredConfigPath = "/run/measured-cfg"
27+
insecureConfigPath = "/run/insecure-cfg"
28+
initdataProcessorConfigKey = "contrast-initdata-processor.json"
2829
)
2930

3031
var version = "0.0.0-dev"
@@ -100,28 +101,54 @@ func handleInitdata(doc initdata.Raw) (hostdata []byte, insecurePlatform bool, r
100101
return nil, false, fmt.Errorf("computing initdata digest: %w", err)
101102
}
102103

103-
v, verr := validator.New()
104-
if errors.Is(verr, validator.ErrNoPlatform) {
105-
log.Print("WARNING: No TEE platform detected, skipping initdata digest validation. This is expected on insecure platforms.")
106-
insecurePlatform = true
107-
} else if verr != nil {
108-
return nil, false, fmt.Errorf("creating validator: %w", verr)
109-
} else if err := v.ValidateDigest(digest); err != nil {
110-
return nil, false, fmt.Errorf("validating initdata digest: %w", err)
111-
}
112-
113104
data, err := doc.Parse()
114105
if err != nil {
115106
return nil, false, fmt.Errorf("parsing initdata: %w", err)
116107
}
108+
processorConfig, err := parseProcessorConfig(data.Data)
109+
if err != nil {
110+
return nil, false, err
111+
}
112+
if processorConfig.Insecure {
113+
log.Print("WARNING: Insecure initdata requested, skipping TEE initdata digest validation.")
114+
} else {
115+
v, err := validator.New()
116+
if err != nil {
117+
return nil, false, fmt.Errorf("creating validator: %w", err)
118+
}
119+
if err := v.ValidateDigest(digest); err != nil {
120+
return nil, false, fmt.Errorf("validating initdata digest: %w", err)
121+
}
122+
}
117123
for name, content := range data.Data {
118124
name = filepath.Clean(name)
119125
path := filepath.Join(measuredConfigPath, name)
120126
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
121127
return nil, false, fmt.Errorf("writing file %q: %w", path, err)
122128
}
123129
}
124-
return digest, insecurePlatform, nil
130+
return digest, processorConfig.Insecure, nil
131+
}
132+
133+
type processorConfig struct {
134+
// Insecure allows running workloads on non-TEE development platforms.
135+
// When set, the initdata-processor serves the initdata digest to the
136+
// insecure attestation issuer via HTTP instead of validating it against
137+
// TEE hostdata.
138+
Insecure bool `json:"insecure"`
139+
}
140+
141+
func parseProcessorConfig(data map[string]string) (processorConfig, error) {
142+
configJSON, ok := data[initdataProcessorConfigKey]
143+
if !ok {
144+
return processorConfig{}, nil
145+
}
146+
147+
var config processorConfig
148+
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
149+
return processorConfig{}, fmt.Errorf("parsing %q: %w", initdataProcessorConfigKey, err)
150+
}
151+
return config, nil
125152
}
126153

127154
// serveHostdata starts an HTTP server that serves the hostdata digest.

initdata-processor/main_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2026 Edgeless Systems GmbH
2+
// SPDX-License-Identifier: BUSL-1.1
3+
4+
package main
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestParseProcessorConfig(t *testing.T) {
14+
tests := map[string]struct {
15+
data map[string]string
16+
wantInsecure bool
17+
wantErr bool
18+
}{
19+
"missing": {},
20+
"insecure": {
21+
data: map[string]string{
22+
initdataProcessorConfigKey: `{"insecure": true}`,
23+
},
24+
wantInsecure: true,
25+
},
26+
"secure": {
27+
data: map[string]string{
28+
initdataProcessorConfigKey: `{"insecure": false}`,
29+
},
30+
},
31+
"invalid": {
32+
data: map[string]string{
33+
initdataProcessorConfigKey: `{insecure: true}`,
34+
},
35+
wantErr: true,
36+
},
37+
}
38+
39+
for name, tc := range tests {
40+
t.Run(name, func(t *testing.T) {
41+
config, err := parseProcessorConfig(tc.data)
42+
if tc.wantErr {
43+
require.Error(t, err)
44+
return
45+
}
46+
require.NoError(t, err)
47+
assert.Equal(t, tc.wantInsecure, config.Insecure)
48+
})
49+
}
50+
}

internal/initdata/initdata_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ func buildTemplate(algorithm, version string, data bool) Raw {
2828
if version != "" {
2929
fmt.Fprintf(&builder, "version = \"%s\"\n", version)
3030
}
31-
3231
if data {
3332
builder.WriteString(`
3433
[data]
@@ -159,6 +158,7 @@ func TestEncode(t *testing.T) {
159158

160159
assert.Contains(tomlString, fmt.Sprintf("version = '%s'", tc.version))
161160
assert.Contains(tomlString, fmt.Sprintf("algorithm = '%s'", tc.algorithm))
161+
assert.NotContains(tomlString, "insecure")
162162
for key, value := range tc.data {
163163
if strings.Contains(key, ".") {
164164
key = fmt.Sprintf("'%s'", key)

0 commit comments

Comments
 (0)