policy

package
v0.0.0-...-4e66fdd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2024 License: Apache-2.0 Imports: 18 Imported by: 1

README

Policies allow tenants to perform additional evaluation of attestation evidence that is not covered by a particular attestation scheme. The policy can be used to override the overall attestation status and/or the trust vector values in the result (e.g. rejecting a token considered valid by the scheme if the more stringent constraints described in the policy are not met).

Note Policy administration framework is to be determined in the future. The short-term plan is to make this a part of the deployment flow, but a more complete policy admin flow may follow.

The syntax of the policy depends on the agent used to evaluate it. At the moment, the following policy agents are supported:

"opa" -- Open Policy Agent is a flexible, generic Open Source policy agent that utilizes its own policy language called Rego. See README.opa.md.

Configuration

The following policy agent configuration directives are currently supported:

  • backend: specified which policy backend will be used. Currently supported backends: opa.
  • <backend name>: an entry with the name of a backend is used to specify configuration for that backend. Multiple such entries may exist in a single config, but only the one for the backend specified by the backend directive will be used.

opa backend configuration

Currently, opa backend does not support any configuration.

Policy Identification

There are three different ways of identifying a policy:

appraisal policy ID

This is an identifier used in the attestation result as defined by EAR Internet draft. Note that in this case, "policy" is used in the sense of "Appraisal Policy for Evidence" as per RATS architecture. In Veraison, this encompasses both, the scheme, and the policy applied from the policy store by a policy engine.

An appraisal policy ID is a URI with the scheme policy followed by a rootless path indicating the (RATS) policy using which the appraisal has been generated. The first segment of the path is the name of the scheme used to create the appraisal. The second segment, if present, is the individual policy ID (see below) of the policy that has been applied to the appraisal created by the scheme.

For example:

  • policy:TPM_ENACTTRUST: the appraisal has been created using "TPM_ENACTTRUST" scheme, with no additional policy applied.
  • policy:PSA_IOT/340d22f7-9eda-499f-9aa2-5af295d6d812: the appraisal has been created using "PSA_IOT" scheme and has subsequently been updated by the policy with unique policy ID "ae19cc27-a449-1fb8-6c10-00f47ad1c55c".
Potential future extensions

These indicate potential future enhancements, and are not supported by the current implementation.

Cascading policies

In the future we may support applying multiple individual policies to a single appraisal. In that case, each path segment after the first (the scheme) is the individual policy ID of a policy that has been applied. The ordering of the segments matches the order in which the policies were applied.

For example:

  • policy:PSA_IOT/340d22f7-9eda-499f-9aa2-5af295d6d812/ae19cc27-a449-1fb8-6c10-00f47ad1c55c: the appraisal has been created using "PSA_IOT" scheme, it was then updated by a policy with the individual policy id 340d22f7-9eda-499f-9aa2-5af295d6d812, followed by a policy with the individual policy ID ae19cc27-a449-1fb8-6c10-00f47ad1c55c.

policy store key

Policies are stored, retrieved from, and updated in the policy store using a key. The key is a string consisting of the tenant id, scheme, and policy name delimited by colons.

For example:

  • 0:PSA_IOT:opa: the key for tenant "0"'s policy for scheme "PSA_IOT" with name "opa".
policy name

The name exists to support cascading policies in the future (see above). At the moment, as there is only one active policy allowed per appraisal, the name is not necessary and is always set to the name of the policy engine ("opa"). While this unnecessarily increases the key size and is somewhat wasteful, given that the number of the policies a typical deployment is expected to be, at most, in the hundreds, and the relatively negligible overhead compared to the size of the policies themselves, this is not deemed to be a major concern.

individual policy ID

The individual policy ID identifies the specific policy that was applied to an appraisal. It forms a component of the appraisal policy ID (which also includes the scheme, and possibly, in the future, individual IDs from multiple policies). It differs from the policy store key in that it also incorporates versioning information.

The individual policy id is the UUID of the specific policy instance.

For example: 340d22f7-9eda-499f-9aa2-5af295d6d812

Documentation

Overview

Copyright 2022-2023 Contributors to the Veraison project. SPDX-License-Identifier: Apache-2.0

Copyright 2022-2023 Contributors to the Veraison project. SPDX-License-Identifier: Apache-2.0

Copyright 2022-2023 Contributors to the Veraison project. SPDX-License-Identifier: Apache-2.0

Copyright 2022-2023 Contributors to the Veraison project. SPDX-License-Identifier: Apache-2.0

Copyright 2022-2023 Contributors to the Veraison project. SPDX-License-Identifier: Apache-2.0

Copyright 2022-2023 Contributors to the Veraison project. SPDX-License-Identifier: Apache-2.0

Copyright 2022-2023 Contributors to the Veraison project. SPDX-License-Identifier: Apache-2.0

Copyright 2022-2023 Contributors to the Veraison project. SPDX-License-Identifier: Apache-2.0

Index

Constants

This section is empty.

Variables

View Source
var DefaultBackend = "opa"

DefaultBackend will be used if backend is not explicitly specfied

View Source
var ErrBadOPAResult = errors.New("bad result update from policy")
View Source
var ErrBadResult = "could not create updated AttestationResult: %w from JSON %s"
View Source
var ErrNoActivePolicy = errors.New("no active policy for key")
View Source
var ErrNoPolicy = errors.New("no policy found")
View Source
var ErrNoStatus = "backend returned outcome with no status field: %v"
View Source
var ErrNoTV = "backend returned no trust-vector field, or its not a map[string]interface{}: %v"

Functions

func GetSupportedAgentBackends

func GetSupportedAgentBackends() []string

GetSupportedBackends returns a string slice of supported backend names.

func IsValidAgentBackend

func IsValidAgentBackend(name string) bool

IsValidAgentBackend returns True iff the specified string names a valid backend.

Types

type Agent

type Agent struct {
	Backend IBackend
	// contains filtered or unexported fields
}

func (*Agent) Close

func (o *Agent) Close()

func (*Agent) Evaluate

func (o *Agent) Evaluate(
	ctx context.Context,
	sessionContext map[string]interface{},
	scheme string,
	policy *Policy,
	submod string,
	appraisal *ear.Appraisal,
	evidence *proto.EvidenceContext,
	endorsements []string,
) (*ear.Appraisal, error)

Evaluate the provided policy w.r.t. to the specified evidence and endorsements, and return an updated AttestationResult. The policy may overwrite the result status or any of the values in the result trust vector.

func (*Agent) GetBackend

func (o *Agent) GetBackend() IBackend

func (*Agent) GetBackendName

func (o *Agent) GetBackendName() string

GetBackendName returns a string containing the name of the backend used by the agent.

func (*Agent) Init

func (o *Agent) Init(v *viper.Viper) error

func (*Agent) Validate

func (o *Agent) Validate(ctx context.Context, policyRules string) error

Validate performs basic validation of the provided policy rules, returning an error if it fails. the nature of the validation performed is backend-specific, however it would typically amount to a syntax check. Successful validation does not guarantee that the policy will execute correctly againt actual inputs.

type IAgent

type IAgent interface {
	Init(v *viper.Viper) error
	GetBackendName() string
	Evaluate(ctx context.Context,
		appraisalContext map[string]interface{},
		scheme string,
		policy *Policy,
		submod string,
		appraisal *ear.Appraisal,
		evidence *proto.EvidenceContext,
		endorsements []string,
	) (*ear.Appraisal, error)
	Validate(ctx context.Context, policyRules string) error
	Close()
}

func CreateAgent

func CreateAgent(v *viper.Viper, logger *zap.SugaredLogger) (IAgent, error)

CreateAgent creates a new PolicyAgent using the backend specified in the config with "policy.backend" directive. If this directive is absent, the default backend, "opa", will be used.

type IBackend

type IBackend interface {
	Init(v *viper.Viper) error
	GetName() string
	Evaluate(
		ctx context.Context,
		sessionContext map[string]interface{},
		scheme string,
		policy string,
		result map[string]interface{},
		evidence map[string]interface{},
		endorsements []string,
	) (map[string]interface{}, error)
	Validate(ctx context.Context, policy string) error
	Close()
}

type OPA

type OPA struct {
}

func NewOPA

func NewOPA(v *viper.Viper) (*OPA, error)

func (*OPA) Close

func (o *OPA) Close()

func (*OPA) Evaluate

func (o *OPA) Evaluate(
	ctx context.Context,
	sessionContext map[string]interface{},
	scheme string,
	policy string,
	result map[string]interface{},
	evidence map[string]interface{},
	endorsements []string,
) (map[string]interface{}, error)

func (*OPA) GetName

func (o *OPA) GetName() string

func (*OPA) Init

func (o *OPA) Init(v *viper.Viper) error

func (*OPA) Validate

func (o *OPA) Validate(ctx context.Context, policy string) error

type Policy

type Policy struct {
	// StoreKey is the identifier of this policy, unique to the store.
	StoreKey PolicyKey `json:"-"`

	// UUID is the unque identifier associated with this specific instance
	// of a policy.
	UUID uuid.UUID `json:"uuid"`

	// CTime is the creationg time of this policy.
	CTime time.Time `json:"ctime"`

	// Name is the name of this policy. It's a short descritor for the
	// rules in this policy.
	Name string `json:"name"`

	// Type identifies the policy engine used to evaluate the policy, and
	// therfore dictates how the Rules should be interpreted.
	Type string `json:"type"`

	// Rules of the policy to be interpreted and execute by the policy
	// agent.
	Rules string `json:"rules"`

	// Active indicates whether this policy instance is currently active
	// for the associated key.
	Active bool `json:"active"`
}

Policy allows enforcing additional constraints on top of the regular attestation schemes.

func NewPolicy

func NewPolicy(key PolicyKey, name, typ, rules string) (*Policy, error)

NewPolicy creates a new Policy based on the specified PolicyID and rules.

func (*Policy) Validate

func (o *Policy) Validate() error

Validate returns an error if the current policy is invalid.

type PolicyKey

type PolicyKey struct {
	// TenantId  is the ID of the tenant that owns this policy.
	TenantId string `json:"tenant_id"`

	// Scheme is the name of the scheme with which this policy is associated
	Scheme string `json:"scheme"`

	// Name is the name of this policy
	Name string `json:"name"`
}

PolicyKey identifies a specific policy. This is used to retrieve the policy from the store.

func PolicyKeyFromString

func PolicyKeyFromString(s string) (PolicyKey, error)

PolicyKeyFromString parses the specified string containing a policy store key into a PolicyID.

func (PolicyKey) String

func (o PolicyKey) String() string

String returns the string representation of the PolicyKey.

func (PolicyKey) Validate

func (o PolicyKey) Validate() error

type Store

type Store struct {
	KVStore kvstore.IKVStore
	Logger  *zap.SugaredLogger
}

func NewStore

func NewStore(v *viper.Viper, logger *zap.SugaredLogger) (*Store, error)

NewStore returns a new policy store. Config options are the same as those used for kvstore.New().

func (*Store) Activate

func (o *Store) Activate(key PolicyKey, id uuid.UUID) error

Activate activates the policy version with the specified id for the specified key.

func (*Store) Add

func (o *Store) Add(id PolicyKey, name, typ, rules string) (*Policy, error)

Add a policy with the specified ID and rules. If a policy with that ID already exists, an error is returned.

func (*Store) Close

func (o *Store) Close() error

Close the connection to the underlying kvstore.

func (*Store) DeactivateAll

func (o *Store) DeactivateAll(key PolicyKey) error

DeactivateAll deactivates all policies associated with the key.

func (*Store) Del

func (o *Store) Del(key PolicyKey) error

Del removes all policy versions associated with the specified key.

func (*Store) Get

func (o *Store) Get(key PolicyKey) ([]*Policy, error)

Get returns the slice of all Policies associated with the specified ID. Each Policy represents a different version of the same logical policy.

func (*Store) GetActive

func (o *Store) GetActive(key PolicyKey) (*Policy, error)

GetActive returns the current active version of the policy with the specified key, or an error if no such policy exists.

func (*Store) GetPolicy

func (o *Store) GetPolicy(key PolicyKey, id uuid.UUID) (*Policy, error)

GetPolicy returns the policy with the specified UUID under the specified key.

func (*Store) GetPolicyKeys

func (o *Store) GetPolicyKeys() ([]PolicyKey, error)

GetPolicyKeys returns a []PolicyID of the policies currently in the store.

func (*Store) List

func (o *Store) List() ([]*Policy, error)

List returns []Policy containing latest versions of all policies. All policies returned will have distinct IDs. In cases where multiple policies exist for one ID in the store, the latest version will be returned.

func (*Store) ListAllVersions

func (o *Store) ListAllVersions() ([]*Policy, error)

ListAllVersions returns a []Policy containing every policy entry in the underlying store, including multiple versions associated with a single policy ID.

func (*Store) Setup

func (o *Store) Setup() error

Setup the underyling kvstore. This is a one-time setup that only needs to be performed once for a deployment.

func (*Store) Update

func (o *Store) Update(key PolicyKey, name, typ, rules string) (*Policy, error)

Update sets the provided rules as the latest version of the policy with the specified key. If a policy with that key does not exist, it is created.

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL