diff --git a/authorize/evaluator/policy_evaluator_test.go b/authorize/evaluator/policy_evaluator_test.go index 39ea01d8e..f0d7e2c69 100644 --- a/authorize/evaluator/policy_evaluator_test.go +++ b/authorize/evaluator/policy_evaluator_test.go @@ -4,11 +4,13 @@ import ( "context" "strings" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" "github.com/pomerium/pomerium/authorize/internal/store" "github.com/pomerium/pomerium/config" @@ -245,4 +247,51 @@ func TestPolicyEvaluator(t *testing.T) { Traces: []contextutil.PolicyEvaluationTrace{{}, {ID: "p1", Allow: true}}, }, output) }) + t.Run("service account", func(t *testing.T) { + output, err := eval(t, + p1, + []proto.Message{ + u1, + &user.ServiceAccount{ + Id: "sa1", + UserId: "u1", + }, + }, + &PolicyRequest{ + HTTP: RequestHTTP{Method: "GET", URL: "https://from.example.com/path"}, + Session: RequestSession{ID: "sa1"}, + + IsValidClientCertificate: true, + }) + require.NoError(t, err) + assert.Equal(t, &PolicyResponse{ + Allow: NewRuleResult(true, criteria.ReasonEmailOK), + Deny: NewRuleResult(false, criteria.ReasonValidClientCertificateOrNoneRequired), + Traces: []contextutil.PolicyEvaluationTrace{{Allow: true}}, + }, output) + }) + t.Run("expired service account", func(t *testing.T) { + output, err := eval(t, + p1, + []proto.Message{ + u1, + &user.ServiceAccount{ + Id: "sa1", + UserId: "u1", + ExpiresAt: timestamppb.New(time.Now().Add(-time.Second)), + }, + }, + &PolicyRequest{ + HTTP: RequestHTTP{Method: "GET", URL: "https://from.example.com/path"}, + Session: RequestSession{ID: "sa1"}, + + IsValidClientCertificate: true, + }) + require.NoError(t, err) + assert.Equal(t, &PolicyResponse{ + Allow: NewRuleResult(false, criteria.ReasonNonPomeriumRoute, criteria.ReasonUserUnauthenticated), + Deny: NewRuleResult(false, criteria.ReasonValidClientCertificateOrNoneRequired), + Traces: []contextutil.PolicyEvaluationTrace{{Allow: false}}, + }, output) + }) } diff --git a/authorize/internal/store/store.go b/authorize/internal/store/store.go index e4ad99f4b..738960902 100644 --- a/authorize/internal/store/store.go +++ b/authorize/internal/store/store.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "time" "github.com/go-jose/go-jose/v3" "github.com/open-policy-agent/opa/ast" @@ -13,6 +14,7 @@ import ( "github.com/open-policy-agent/opa/storage/inmem" "github.com/open-policy-agent/opa/types" "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/timestamppb" "github.com/pomerium/pomerium/config" "github.com/pomerium/pomerium/internal/log" @@ -131,10 +133,16 @@ func (s *Store) GetDataBrokerRecordOption() func(*rego.Rego) { msg, _ := res.GetRecords()[0].GetData().UnmarshalNew() if msg == nil { - if msg == nil { + return ast.NullTerm(), nil + } + + // exclude expired records + if hasExpiresAt, ok := msg.(interface{ GetExpiresAt() *timestamppb.Timestamp }); ok && hasExpiresAt.GetExpiresAt() != nil { + if hasExpiresAt.GetExpiresAt().AsTime().Before(time.Now()) { return ast.NullTerm(), nil } } + obj := toMap(msg) regoValue, err := ast.InterfaceToValue(obj)