Skip to content

Commit

Permalink
rework OPA policies with go embed
Browse files Browse the repository at this point in the history
Signed-off-by: denis-tingajkin <denis.tingajkin@xored.com>
  • Loading branch information
denis-tingaikin committed Jul 13, 2021
1 parent d11653e commit aa97513
Show file tree
Hide file tree
Showing 17 changed files with 349 additions and 223 deletions.
3 changes: 3 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ issues:
linters:
- dupl
- golint
- path: pkg/tools/opa/policies.go
linters:
- golint
- path: .*registry.*.go
linters:
- dupl
Expand Down
8 changes: 7 additions & 1 deletion pkg/networkservice/common/authorize/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/networkservicemesh/api/pkg/api/networkservice"

"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"
"github.com/networkservicemesh/sdk/pkg/tools/opa"
)

type authorizeClient struct {
Expand All @@ -39,7 +40,12 @@ type authorizeClient struct {
// NewClient - returns a new authorization networkservicemesh.NetworkServiceClient
func NewClient(opts ...Option) networkservice.NetworkServiceClient {
var result = &authorizeClient{
policies: defaultPolicies(),
policies: []Policy{
opa.WithTokensValidPolicy(),
opa.WithCurrentTokenSignedPolicy(),
opa.WithTokensExpiredPolicy(),
opa.WithTokenChainPolicy(),
},
}
for _, o := range opts {
o.apply(&result.policies)
Expand Down
11 changes: 0 additions & 11 deletions pkg/networkservice/common/authorize/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import (
"context"

"github.com/networkservicemesh/api/pkg/api/networkservice"

"github.com/networkservicemesh/sdk/pkg/tools/opa"
)

// Policy represents authorization policy for network service.
Expand All @@ -46,12 +44,3 @@ func (l *policiesList) check(ctx context.Context, conn *networkservice.Connectio
}
return nil
}

func defaultPolicies() policiesList {
return []Policy{
opa.WithAllTokensValidPolicy(),
opa.WithLastTokenSignedPolicy(),
opa.WithTokensExpiredPolicy(),
opa.WithTokenChainPolicy(),
}
}
18 changes: 12 additions & 6 deletions pkg/networkservice/common/authorize/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,27 @@ import (
"github.com/networkservicemesh/api/pkg/api/networkservice"

"github.com/networkservicemesh/sdk/pkg/networkservice/core/next"
"github.com/networkservicemesh/sdk/pkg/tools/opa"
)

type authorizeServer struct {
policies *policiesList
policies policiesList
}

// NewServer - returns a new authorization networkservicemesh.NetworkServiceServers
func NewServer(opts ...Option) networkservice.NetworkServiceServer {
p := &policiesList{}
for _, o := range opts {
o.apply(p)
var s = &authorizeServer{
policies: []Policy{
opa.WithTokensValidPolicy(),
opa.WithCurrentTokenSignedPolicy(),
opa.WithTokensExpiredPolicy(),
opa.WithTokenChainPolicy(),
},
}
return &authorizeServer{
policies: p,
for _, o := range opts {
o.apply(&s.policies)
}
return s
}

func (a *authorizeServer) Request(ctx context.Context, request *networkservice.NetworkServiceRequest) (*networkservice.Connection, error) {
Expand Down
47 changes: 0 additions & 47 deletions pkg/tools/opa/all_tokens_valid_policy.go

This file was deleted.

4 changes: 2 additions & 2 deletions pkg/tools/opa/all_tokens_valid_policy_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020 Doc.ai and/or its affiliates.
// Copyright (c) 2020-2021 Doc.ai and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
Expand Down Expand Up @@ -56,7 +56,7 @@ func TestWithAllTokensValidPolicy(t *testing.T) {
},
}

p := opa.WithAllTokensValidPolicy()
p := opa.WithTokensValidPolicy()
err := p.Check(context.Background(), validPath)
require.Nil(t, err)
err = p.Check(context.Background(), invalidPath)
Expand Down
85 changes: 85 additions & 0 deletions pkg/tools/opa/current_token_signed_policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright (c) 2020-2021 Doc.ai and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package opa_test

import (
"context"
"crypto/tls"
"crypto/x509"
"testing"

"github.com/dgrijalva/jwt-go"
"github.com/networkservicemesh/api/pkg/api/networkservice"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/peer"

"github.com/networkservicemesh/sdk/pkg/tools/opa"
)

func Test_CurrentTokenShouldBeSigned_Server(t *testing.T) {
ca, err := generateCA()
require.Nil(t, err)

cert, err := generateKeyPair(spiffeID, "test.com", &ca)
require.Nil(t, err)

token, err := jwt.New(jwt.SigningMethodES256).SignedString(cert.PrivateKey)
require.Nil(t, err)

validX509crt, err := x509.ParseCertificate(cert.Certificate[0])
require.Nil(t, err)

p := opa.WithCurrentTokenSignedPolicy()

samples := []*networkservice.Path{
{
PathSegments: []*networkservice.PathSegment{
{
Token: token,
},
},
},
}

peerAuth := &peer.Peer{
AuthInfo: &credentials.TLSInfo{
State: tls.ConnectionState{
PeerCertificates: []*x509.Certificate{
validX509crt,
},
},
},
}

ctx := peer.NewContext(context.Background(), peerAuth)

for i, input := range samples {
peerAuth.AuthInfo.(*credentials.TLSInfo).State.PeerCertificates[0] = validX509crt

err = p.Check(ctx, input)
require.NoError(t, err, i)

invalidX509crt, err := x509.ParseCertificate(ca.Certificate[0])
require.NoError(t, err)

peerAuth.AuthInfo.(*credentials.TLSInfo).State.PeerCertificates[0] = invalidX509crt

err = p.Check(ctx, input)
require.Error(t, err)
}
}
52 changes: 0 additions & 52 deletions pkg/tools/opa/last_token_signed_policy.go

This file was deleted.

79 changes: 79 additions & 0 deletions pkg/tools/opa/policies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) 2020-2021 Doc.ai and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package opa

import _ "embed"

//go:embed policies/tokens_valid.opa
var tokensValidPolicySource string

//go:embed policies/prev_token_signed.opa
var prevTokenSignedPolicySource string

//go:embed policies/curr_token_signed.opa
var currTokenSignedPolicySource string

//go:embed policies/tokens_chained.opa
var tokensChainedPolicySource string

//go:embed policies/tokens_expired.opa
var tokensExpiredPolicySource string

// WithTokensValidPolicy returns default policy for checking that all tokens in the path can be decoded.
func WithTokensValidPolicy() *AuthorizationPolicy {
return &AuthorizationPolicy{
policySource: tokensValidPolicySource,
query: "tokens_valid",
checker: True("tokens_valid"),
}
}

// WithCurrentTokenSignedPolicy returns default policy for checking that last token in path is signed.
func WithCurrentTokenSignedPolicy() *AuthorizationPolicy {
return &AuthorizationPolicy{
policySource: currTokenSignedPolicySource,
query: "curr_token_signed",
checker: True("curr_token_signed"),
}
}

// WithPrevTokenSignedPolicy returns default policy for checking that last token in path is signed.
func WithPrevTokenSignedPolicy() *AuthorizationPolicy {
return &AuthorizationPolicy{
policySource: prevTokenSignedPolicySource,
query: "prev_token_signed",
checker: True("prev_token_signed"),
}
}

// WithTokenChainPolicy returns default policy for checking tokens chain in path
func WithTokenChainPolicy() *AuthorizationPolicy {
return &AuthorizationPolicy{
policySource: tokensChainedPolicySource,
query: "tokens_chained",
checker: True("tokens_chained"),
}
}

// WithTokensExpiredPolicy returns default policy for checking tokens expiration
func WithTokensExpiredPolicy() *AuthorizationPolicy {
return &AuthorizationPolicy{
policySource: tokensExpiredPolicySource,
query: "tokens_expired",
checker: False("tokens_expired"),
}
}
28 changes: 28 additions & 0 deletions pkg/tools/opa/policies/curr_token_signed.opa
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (c) 2020 Cisco and/or its affiliates.
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

package nsm

default curr_token_signed = false
default index = 0

index = input.index

curr_token_signed {
token := input.path_segments[index].token
cert := input.auth_info.certificate
io.jwt.verify_es256(token, cert) = true
}
Loading

0 comments on commit aa97513

Please sign in to comment.