Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 34 additions & 9 deletions vts/appraisal/appraisal.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022-2023 Contributors to the Veraison project.
// Copyright 2022-2026 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0

package appraisal
Expand All @@ -12,6 +12,7 @@ import (
"github.com/veraison/services/config"
"github.com/veraison/services/policy"
"github.com/veraison/services/proto"
"google.golang.org/protobuf/types/known/structpb"
)

// Appraisal provides an appraisal context internally within the VTS (e.g. for
Expand All @@ -22,6 +23,7 @@ type Appraisal struct {
EvidenceContext *proto.EvidenceContext
Result *ear.AttestationResult
SignedEAR []byte
Endorsements []string
}

func New(tenantID string, nonce []byte, scheme string) *Appraisal {
Expand All @@ -33,31 +35,52 @@ func New(tenantID string, nonce []byte, scheme string) *Appraisal {
Result: ear.NewAttestationResult(scheme, config.Version, config.Developer),
}

encodedNonce := base64.URLEncoding.EncodeToString(nonce)
appraisal.Result.Nonce = &encodedNonce

appraisal.Result.VerifierID.Build = &config.Version
appraisal.Result.VerifierID.Developer = &config.Developer

appraisal.setResultNonce(nonce)
appraisal.InitPolicyID()

return &appraisal
}

func (o *Appraisal) setResultNonce(v []byte) {
encodedNonce := base64.URLEncoding.EncodeToString(v)
o.Result.Nonce = &encodedNonce
}

func (o *Appraisal) SetTrustAnchorIDs(v []string) {
o.EvidenceContext.TrustAnchorIds = v
}

func (o *Appraisal) SetReferenceIDs(v []string) {
o.EvidenceContext.ReferenceIds = v
}

func (o *Appraisal) SetEvidenceClaims(v *structpb.Struct) {
o.EvidenceContext.Evidence = v
}

func (o *Appraisal) SetEndorsements(v []string) {
o.Endorsements = v
}

func (o *Appraisal) SetResultWithNonce(result *ear.AttestationResult, nonce []byte) {
o.Result = result
o.setResultNonce(nonce)
}

func (o Appraisal) GetContext() *proto.AppraisalContext {
return &proto.AppraisalContext{
Evidence: o.EvidenceContext,
Result: o.SignedEAR,
}
}

func (o Appraisal) SetAllClaims(claim ear.TrustClaim) {
func (o *Appraisal) SetAllClaims(claim ear.TrustClaim) {
for _, submod := range o.Result.Submods {
submod.TrustVector.SetAll(claim)
}
}

func (o Appraisal) AddPolicyClaim(name, claim string) {
func (o *Appraisal) AddPolicyClaim(name, claim string) {
for _, submod := range o.Result.Submods {
if submod.AppraisalExtensions.VeraisonPolicyClaims == nil {
claimsMap := make(map[string]interface{})
Expand All @@ -82,6 +105,8 @@ func (o *Appraisal) UpdatePolicyID(pol *policy.Policy) error {
return nil
}

// InitPolicyID must be called before sending the appraisal to policy manager
// for evaluation.
func (o *Appraisal) InitPolicyID() {
for _, submod := range o.Result.Submods {
policyID := fmt.Sprintf("policy:%s", o.Scheme)
Expand Down
13 changes: 13 additions & 0 deletions vts/policymanager/ipolicymanager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2026 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0
package policymanager

import (
"context"

"github.com/veraison/services/vts/appraisal"
)

type IPolicyManager interface {
Evaluate(ctx context.Context, appraisal *appraisal.Appraisal) error
}
17 changes: 8 additions & 9 deletions vts/policymanager/policymanager.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022-2024 Contributors to the Veraison project.
// Copyright 2022-2026 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0
package policymanager

Expand Down Expand Up @@ -32,13 +32,12 @@ func New(v *viper.Viper, store *policy.Store, logger *zap.SugaredLogger) (*Polic
return pm, nil
}

// XXX(tho) revisit coupling between appraisal and policy manager
func (o *PolicyManager) Evaluate(
ctx context.Context,
scheme string,
appraisal *appraisal.Appraisal,
endorsements []string,
) error {
policyKey := o.getPolicyKey(appraisal)
policyKey := o.getPolicyKey(appraisal.EvidenceContext.TenantId, appraisal.Scheme)

pol, err := o.getPolicy(policyKey)
if err != nil {
Expand All @@ -58,12 +57,12 @@ func (o *PolicyManager) Evaluate(
evaluated, err := o.Agent.Evaluate(
ctx,
appraisalContext,
scheme,
appraisal.Scheme,
pol,
submod,
submodAppraisal,
appraisal.EvidenceContext,
endorsements,
appraisal.Endorsements,
)
if err != nil {
return err
Expand All @@ -77,10 +76,10 @@ func (o *PolicyManager) Evaluate(
return nil
}

func (o *PolicyManager) getPolicyKey(a *appraisal.Appraisal) policy.PolicyKey {
func (o *PolicyManager) getPolicyKey(tenantID string, scheme string) policy.PolicyKey {
return policy.PolicyKey{
TenantId: a.EvidenceContext.TenantId,
Scheme: a.Scheme,
TenantId: tenantID,
Scheme: scheme,
Name: o.Agent.GetBackendName(),
}
}
Expand Down
17 changes: 9 additions & 8 deletions vts/policymanager/policymanager_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022-2023 Contributors to the Veraison project.
// Copyright 2022-2026 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0
package policymanager

Expand Down Expand Up @@ -48,7 +48,7 @@ func TestPolicyMgr_getPolicy_not_found(t *testing.T) {
pm := &PolicyManager{Store: &policy.Store{KVStore: store, Logger: log.Named("test")},
Agent: agent}

polKey := pm.getPolicyKey(appraisal)
polKey := pm.getPolicyKey(appraisal.EvidenceContext.TenantId, appraisal.Scheme)
assert.Equal(t, "0:TPM_ENACTTRUST:opa", polKey.String())

pol, err := pm.getPolicy(polKey)
Expand Down Expand Up @@ -82,7 +82,7 @@ func TestPolicyMgr_getPolicy_OK(t *testing.T) {

pm := &PolicyManager{Store: &policy.Store{KVStore: store}, Agent: agent}

polKey := pm.getPolicyKey(appraisal)
polKey := pm.getPolicyKey(appraisal.EvidenceContext.TenantId, appraisal.Scheme)
assert.Equal(t, "0:TPM_ENACTTRUST:opa", polKey.String())

_, err = pm.getPolicy(polKey)
Expand Down Expand Up @@ -129,6 +129,7 @@ func TestPolicyMgr_Evaluate_OK(t *testing.T) {
endorsements := []string{"h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc="}
ar := ear.NewAttestationResult("test", "test", "test")
ap := &appraisal.Appraisal{EvidenceContext: ec, Result: ar, Scheme: "TPM_ENACTTRUST"}
ap.Endorsements = endorsements

polID := "policy:TPM_ENACTTRUST"
tier := ear.TrustTierAffirming
Expand All @@ -140,7 +141,7 @@ func TestPolicyMgr_Evaluate_OK(t *testing.T) {
Evaluate(
context.TODO(),
gomock.Any(),
"test",
"TPM_ENACTTRUST",
gomock.Any(),
gomock.Any(),
ar.Submods["test"],
Expand All @@ -153,7 +154,7 @@ func TestPolicyMgr_Evaluate_OK(t *testing.T) {
Agent: agent,
logger: log.Named("manager"),
}
err := pm.Evaluate(context.TODO(), "test", ap, endorsements)
err := pm.Evaluate(context.TODO(), ap)
require.NoError(t, err)
}

Expand All @@ -174,17 +175,17 @@ func TestPolicyMgr_Evaluate_NOK(t *testing.T) {
}
endorsements := []string{"h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc="}
ar := ear.NewAttestationResult("test", "test", "test")
ap := &appraisal.Appraisal{EvidenceContext: ec, Result: ar, Scheme: "TPM_ENACTTRUST"}
ap := &appraisal.Appraisal{EvidenceContext: ec, Result: ar, Scheme: "TPM_ENACTTRUST", Endorsements: endorsements}
expectedErr := errors.New("could not evaluate policy: policy returned bad update")
agent := mock_deps.NewMockIAgent(ctrl)
agent.EXPECT().GetBackendName().Return("opa")
agent.EXPECT().Evaluate(context.TODO(), gomock.Any(), "test", gomock.Any(), gomock.Any(), ar.Submods["test"], ec, endorsements).Return(nil, expectedErr)
agent.EXPECT().Evaluate(context.TODO(), gomock.Any(), "TPM_ENACTTRUST", gomock.Any(), gomock.Any(), ar.Submods["test"], ec, endorsements).Return(nil, expectedErr)
pm := &PolicyManager{
Store: &policy.Store{KVStore: store, Logger: log.Named("store")},
Agent: agent,
logger: log.Named("manager"),
}
err := pm.Evaluate(context.TODO(), "test", ap, endorsements)
err := pm.Evaluate(context.TODO(), ap)
assert.ErrorIs(t, err, expectedErr)

}
12 changes: 11 additions & 1 deletion vts/trustedservices/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,17 @@

GOPKG := github.com/veraison/services/vts/trustedservices

all-hook-pre test-hook-pre lint-hook-pre:
INTERFACES += ../../plugin/imanager.go
INTERFACES += ../../plugin/ipluggable.go
INTERFACES += ../earsigner/iearsigner.go
INTERFACES += ../../handler/ievidencehandler.go
INTERFACES += ../../handler/istorehandler.go
INTERFACES += ../../kvstore/ikvstore.go
INTERFACES += ../policymanager/ipolicymanager.go

MOCKPKG := mocks

all-hook-pre test-hook-pre lint-hook-pre: _mocks
$(MAKE) -C ../../proto protogen

include ../../mk/common.mk
Expand Down
97 changes: 97 additions & 0 deletions vts/trustedservices/mocks/iearsigner.go

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

Loading
Loading