Skip to content

Commit

Permalink
implement now policy/spec format
Browse files Browse the repository at this point in the history
  • Loading branch information
jessieqliu committed Oct 1, 2024
1 parent 466733f commit 43c5589
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 49 deletions.
62 changes: 62 additions & 0 deletions launcher/internal/healthmonitoring/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package monitoring

import (
"fmt"
"strings"
)

type Config struct {
CPU bool
Disk bool
Host bool
Memory bool
}

func AllConfig() Config {
return Config{CPU: true, Disk: true, Host: true, Memory: true}
}

func NoneConfig() Config {
return Config{CPU: false, Disk: false, Host: false, Memory: false}
}

func ToConfig(data string) (Config, error) {
// We currently only support a single value for this field.
switch strings.ToLower(data) {
case "none":
return NoneConfig(), nil
case "all":
return AllConfig(), nil
case "memory":
return Config{Memory: true}, nil
}

return Config{}, fmt.Errorf("invalid monitoring type: %v", data)
}

// Verifies that each monitoring component enabled by spec is also enabled by policy.
func CheckCompliance(policy Config, spec Config) error {
invalidConfigs := []string{}

if !policy.CPU && spec.CPU {
invalidConfigs = append(invalidConfigs, "CPU")
}

if !policy.Disk && spec.Disk {
invalidConfigs = append(invalidConfigs, "DISK")
}

if !policy.Host && spec.Host {
invalidConfigs = append(invalidConfigs, "HOST")
}

if !policy.Memory && spec.Memory {
invalidConfigs = append(invalidConfigs, "MEMORY")
}

if len(invalidConfigs) > 0 {
return fmt.Errorf("the following monitoring types were enabled, but disallowed by launch policy: %v", invalidConfigs)
}

return nil
}
60 changes: 19 additions & 41 deletions launcher/spec/launch_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"path/filepath"
"strconv"
"strings"

"github.com/google/go-tpm-tools/launcher/internal/healthmonitoring/monitoring"

Check failure on line 11 in launcher/spec/launch_policy.go

View workflow job for this annotation

GitHub Actions / Release (ubuntu-latest, Go 1.21.x)

no required module provides package github.com/google/go-tpm-tools/launcher/internal/healthmonitoring/monitoring; to add it:

Check failure on line 11 in launcher/spec/launch_policy.go

View workflow job for this annotation

GitHub Actions / Generate/Build/Test (ubuntu-latest, x64, Go 1.21.x)

no required module provides package github.com/google/go-tpm-tools/launcher/internal/healthmonitoring/monitoring; to add it:
)

// LaunchPolicy contains policies on starting the container.
Expand All @@ -16,8 +18,8 @@ type LaunchPolicy struct {
AllowedCmdOverride bool
AllowedLogRedirect policy
AllowedMountDestinations []string
HardenedImageMonitoring monitoringType
DebugImageMonitoring monitoringType
HardenedImageMonitoring monitoring.Config
DebugImageMonitoring monitoring.Config
}

type policy int
Expand Down Expand Up @@ -100,57 +102,45 @@ func configureMonitoringPolicy(imageLabels map[string]string, launchPolicy *Laun

logger.Printf("%s will be deprecated, use %s and %s instead", memoryMonitoring, hardenedMonitoring, debugMonitoring)

memoryOnlyConfig := monitoring.Config{CPU: false, Disk: false, Host: false, Memory: false}
switch policy {
case always:
logger.Printf("%s=always, will be treated as %s=memory_only and %s=memory_only", memoryMonitoring, hardenedMonitoring, debugMonitoring)
launchPolicy.HardenedImageMonitoring = memoryOnly
launchPolicy.DebugImageMonitoring = memoryOnly
logger.Printf("%s=always, will be treated as %s=memory and %s=memory", memoryMonitoring, hardenedMonitoring, debugMonitoring)
launchPolicy.HardenedImageMonitoring = memoryOnlyConfig
launchPolicy.DebugImageMonitoring = memoryOnlyConfig
case never:
logger.Printf("%s=never, will be treated as %s=none and %s=none", memoryMonitoring, hardenedMonitoring, debugMonitoring)
launchPolicy.HardenedImageMonitoring = none
launchPolicy.DebugImageMonitoring = none
launchPolicy.HardenedImageMonitoring = memoryOnlyConfig
launchPolicy.DebugImageMonitoring = monitoring.NoneConfig()
case debugOnly:
logger.Printf("%s=debug_only, will be treated as %s=none and %s=memory_only", memoryMonitoring, hardenedMonitoring, debugMonitoring)
launchPolicy.HardenedImageMonitoring = none
launchPolicy.DebugImageMonitoring = memoryOnly
logger.Printf("%s=debug_only, will be treated as %s=none and %s=memory", memoryMonitoring, hardenedMonitoring, debugMonitoring)
launchPolicy.HardenedImageMonitoring = monitoring.NoneConfig()
launchPolicy.DebugImageMonitoring = memoryOnlyConfig
}
return nil
}

if hardenedOk {
launchPolicy.HardenedImageMonitoring, err = toMonitoringType(hardenedVal)
launchPolicy.HardenedImageMonitoring, err = monitoring.ToConfig(hardenedVal)
if err != nil {
return fmt.Errorf("invalid monitoring type for hardened image: %v", err)
}
} else {
launchPolicy.HardenedImageMonitoring = none
launchPolicy.HardenedImageMonitoring = monitoring.NoneConfig()
}

if debugOk {
launchPolicy.DebugImageMonitoring, err = toMonitoringType(debugVal)
launchPolicy.DebugImageMonitoring, err = monitoring.ToConfig(debugVal)
if err != nil {
return fmt.Errorf("invalid monitoring type for debug image: %v", err)
}
} else {
launchPolicy.DebugImageMonitoring = health
launchPolicy.DebugImageMonitoring = monitoring.AllConfig()
}

return nil
}

func toMonitoringType(label string) (monitoringType, error) {
switch strings.ToLower(label) {
case "none":
return none, nil
case "memoryonly":
return memoryOnly, nil
case "health":
return health, nil
}

return none, fmt.Errorf("invalid monitoring type: %v", label)
}

// GetLaunchPolicy takes in a map[string] string which should come from image labels,
// and will try to parse it into a LaunchPolicy. Extra fields will be ignored.
func GetLaunchPolicy(imageLabels map[string]string, logger *log.Logger) (LaunchPolicy, error) {
Expand Down Expand Up @@ -224,20 +214,8 @@ func (p LaunchPolicy) Verify(ls LaunchSpec) error {
monitoringPolicy = p.HardenedImageMonitoring
}

if ls.HealthMonitoringEnabled && monitoringPolicy != health {
// Check if there is an issue with the image type.
if ls.Hardened && p.DebugImageMonitoring == health {
return fmt.Errorf("health monitoring only allowed on debug environment by image")
}
return fmt.Errorf("health monitoring not allowed by image")
}

if ls.MemoryMonitoringEnabled && monitoringPolicy == none {
// Check if there is an issue with the image type.
if ls.Hardened && p.DebugImageMonitoring == memoryOnly {
return fmt.Errorf("memory monitoring only allowed on debug environment by image")
}
return fmt.Errorf("memory monitoring not allowed by image")
if err := monitoring.CheckCompliance(monitoringPolicy, ls.MonitoringEnabled); err != nil {
return fmt.Errorf("error verifying monitoring configs: %v", err)
}

var err error
Expand Down
20 changes: 12 additions & 8 deletions launcher/spec/launch_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

"github.com/google/go-tpm-tools/cel"
"github.com/google/go-tpm-tools/launcher/internal/experiments"
monitoring "github.com/google/go-tpm-tools/launcher/internal/healthmonitoring"
"github.com/google/go-tpm-tools/launcher/internal/launchermount"
"github.com/google/go-tpm-tools/launcher/launcherfile"
"github.com/google/go-tpm-tools/verifier/util"
Expand Down Expand Up @@ -83,7 +84,7 @@ const (
attestationServiceAddrKey = "tee-attestation-service-endpoint"
logRedirectKey = "tee-container-log-redirect"
memoryMonitoringEnable = "tee-monitoring-memory-enable"
healthMonitoringEnable = "tee-monitoring-health-enable"
monitoringEnable = "tee-monitoring-enable"
devShmSizeKey = "tee-dev-shm-size-kb"
mountKey = "tee-mount"
)
Expand Down Expand Up @@ -115,7 +116,7 @@ type LaunchSpec struct {
Region string
Hardened bool
MemoryMonitoringEnabled bool
HealthMonitoringEnabled bool
MonitoringEnabled monitoring.Config
LogRedirect LogRedirectLocation
Mounts []launchermount.Mount
// DevShmSize is specified in kiB.
Expand Down Expand Up @@ -157,18 +158,21 @@ func (s *LaunchSpec) UnmarshalJSON(b []byte) error {
}

memVal, memOk := unmarshaledMap[memoryMonitoringEnable]
healthVal, healthOk := unmarshaledMap[healthMonitoringEnable]
monVal, monOk := unmarshaledMap[monitoringEnable]

if memOk && healthOk {
return fmt.Errorf("both %v and %v are specified, only one is permitted", memoryMonitoringEnable, healthMonitoringEnable)
if memOk && monOk {
return fmt.Errorf("both %v and %v are specified, only one is permitted", memoryMonitoringEnable, monitoringEnable)
} else if memOk && memVal != "" {
if boolValue, err := strconv.ParseBool(memVal); err == nil {
s.MemoryMonitoringEnabled = boolValue
}
} else if healthOk && healthVal != "" {
if boolValue, err := strconv.ParseBool(healthVal); err == nil {
s.HealthMonitoringEnabled = boolValue
} else if monOk && monVal != "" {
monCfg, err := monitoring.ToConfig(monVal)
if err != nil {
return err
}

s.MonitoringEnabled = monCfg
}

// Populate cmd override.
Expand Down

0 comments on commit 43c5589

Please sign in to comment.