aserto

package module
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2021 License: Apache-2.0 Imports: 0 Imported by: 0

README

Aserto Go SDK

The aserto-go module provides access to the Aserto authorization service.

Communication with the authorizer service is performed using an AuthorizerClient. The client can be used on its own to make authorization calls or, more commonly, it can be used to create server middleware.

AuthorizerClient

The AuthorizerClient interface, defined in "github.com/aserto-dev/go-grpc-authz/aserto/authorizer/authorizer/v1", describes the operations exposed by the Aserto authorizer service.

Two implementation of AuthorizerClient are available:

  1. client/grpc/authorizer provides a client that communicates with the authorizer using gRPC.

  2. client/http/authorizer provides a client that communicates with the authorizer over its REST HTTP endpoints.

Create a Client

Use authorizer.New() to create a client.

The snippet below creates an authorizer client that talks to Aserto's hosted authorizer over gRPC:

import (
	aserto "github.com/aserto-dev/aserto-go/client"
	"github.com/aserto-dev-aserto-go/client/grpc/authorizer"
)
...
client, err := authorizer.New(
	ctx,
	aserto.WithAPIKeyAuth("<API Key>"),
	aserto.WithTenantID("<Tenant ID>"),
)
Make Authorization Calls

Use the client's Is() method to request authorization decisions from the Aserto authorizer service.

resp, err := client.Is(c.Context, &authz.IsRequest{
	PolicyContext: &api.PolicyContext{
		Id:        "peoplefinder",
		Path:      "peoplefinder.GET.users.__id",
		Decisions: "allowed",
	},
	IdentityContext: &api.IdentityContext{
		Identity: "<user name>",
		Type:     api.IdentityType_IDENTITY_TYPE_SUB,
	},
})

Middleware

Two middleware implementations are available in subpackages:

  • middleware/grpc provides middleware for gRPC servers.
  • middleware/http provides middleware for HTTP REST servers.

When authorization middleware is configured and attached to a server, it examines incoming requests, extracts authorization parameters like the caller's identity, calls the Aserto authorizers, and rejects messages if their access is denied.

Both gRPC and HTTP middleware is created from an AuthorizerClient and configuration for values that are not independent on the content of incoming messages.

// Config holds global authorization options that apply to all requests.
type Config struct {
	// IdentityType describes how identities are interpreted.
	IdentityType api.IdentityType

	// PolicyID is the ID of the aserto policy being queried for authorization.
	PolicyID string

	// PolicyRoot is an optional prefix added to policy paths inferred from messages.
	//
	// For example, if the policy 'peoplefinder.POST.api.users' defines rules for POST requests
	// made to '/api/users', then setting "peoplefinder" as the policy root allows the middleware
	// to infer the correct policy path from incoming requests.
	PolicyRoot string

	// Descision is the authorization rule to use.
	Decision string
}

The value of several authorization parameters often depends on the content of incoming requests. Those are:

  • Identity - the identity (subject or JWT) of the caller.
  • Policy Path - the name of the authorization policy package to evaluate.
  • Resource Context - Additional data sent to the authorizer as JSON.

To produce values for these parameters, each middleware provides hooks in the form of mappers. These are functions that inspect an incoming message and return a value. Middleware accept an identity mapper, a policy mapper - both return strings - and a resource mapper that returns a struct (structpb.Struct).

Mappers are attached using the middleware's With...() methods. The most general of those are:

  • WithIdentityMapper - takes a StringMapper that inspects a message and returns a string to be used as the caller's identity in the authorization request.
  • WithPolicyMapper - takes a StringMapper that inspects a message and returns a string to be used as the Policy Path in the authorization request.
  • WithResouceMapper - takes a StructMapper that inspects a message and returns a *structpb.Struct to be used as the Resource Context in the authorization request.

In addition to these, each middleware has built-in mappers that can handle common use-cases.

gRPC Middleware

The gRPC middleware is available in the sub-package middleware/grpcmw. It implements unary and stream gRPC server interceptors in its .Unary() and .Stream() methods.

middleware, err := grpcmw.NewServerInterceptor(
	client,
	grpcmw.Config{
		IdentityType: api.IdentityType_IDENTITY_TYPE_SUB,
		PolicyID: "<Policy ID>",
		PolicyRoot: "peoplefinder",
		Decision: "allowed",
	},
)

server := grpc.NewServer(grpc.UnaryInterceptor(middleware.Unary))
Mappers

gRPC mappers take as their input the incoming request's context and the message.

type (
	// StringMapper functions are used to extract string values like identity and policy-path from incoming messages.
	StringMapper func(context.Context, interface{}) string

	// StructMapper functions are used to extract a resource context structure from incoming messages.
	StructMapper func(context.Context, interface{}) *structpb.Struct
)

In addition to the general WithIdentityMapper, WithPolicyMapper, and WithResourceMapper, the gRPC middleware provides a set of helper methods that can replace custom user-defined mappers in common use-cases:

  • WithIdentityFromMetadata(field string): Attaches a mapper that retrieves the caller's identity from a metadata.MD field.

  • WithIdentityFromContextValue(value string): Attaches a mapper that retrieves the caller's identity from a Context.Value.

  • WithPolicyPath(path string): Uses the specified policy path in all authorization requests.

  • WithResourceFromFields(fields ...string): Attaches a mapper that constructs a Resource Context from an incoming message by selecting fields, similar to a field mask filter.

Default Mappers

The middleware returned by NewServerInterceptor is configured with the following mappers by default:

  • Identity is pulled form the "authorization" metadata field (i.e. WithIdentityFromMetadata("authorization")).
  • Policy path is constructed as <policy root>.<grpc.Method> where path delimiters (/) are replaced with dots (.).
  • No Resource Context is included in authorization calls by default.

For example, to retrieve the caller's identity from the "username" context value, and set the same policy path ("myPolicy") in all authorization requests:

middlweare.WithIdentityFromContextValue("username").WithPolicyPath("myPolicy")
HTTP Middleware

The HTTP middleware is available in the sub-package middleware/httpmw. It implements the standard net/http middleware signature (func (http.Handler) http.Handler) in its .Handler method.

authz, err := httpmw.NewMiddleware(
	client,
	grpcmw.Config{
		IdentityType: api.IdentityType_IDENTITY_TYPE_SUB,
		PolicyID: "<Policy ID>",
		PolicyRoot: "peoplefinder",
		Decision: "allowed",
	},
)

Adding the created authorization middleware to a basic net/http server may look something like this:

http.Handle("/foo", authz.Handler(fooHandler))

The popular gorilla/mux package provides a powerful and flexible HTTP router. Attaching the authorization middleware to a gorilla/mux server is as simple as:

router := mux.NewRouter()
router.Use(mw)

router.HandleFunc("/foo", fooHandler).Methods("GET")
Mappers

HTTP mappers take the incoming http.Request as their sole parameter.

type (
	StringMapper func(*http.Request) string
	StructMapper func(*http.Request) *structpb.Struct
)

In addition to the general WithIdentityMapper, WithPolicyMapper, and WithResourceMapper, the HTTP middleware provides a set of helper methods that can replace custom user-defined mappers in common use-cases:

  • WithIdentityFromHeader(header string): Attaches a mapper that retrieves the caller's identity from the specified HTTP header.

  • WithPolicyPath(path string): Uses the specified policy path in all authorization requests.

Default Mappers

The middleware returned by NewMiddleware is configured with the following mappers by default:

  • Identity is retrieved from the "Authorization" HTTP Header, if present, and interpreted as an OAuth subject.
  • Policy path is retrieved from the request URL and method to form a path of the form PolicyRoot.METHOD.path.to.endpoint. If the server uses gorilla/mux and the route contains path parameters (e.g. "api/products/{id}"), the surrounding braces are replaced with a double-underscore prefix. For example, with policy root "myApp", a request to GET api/products/{id} gets the policy path myApp.GET.api.products.__id.
  • No Resource Context is included in authorization calls by default.

Other Aserto Services

In addition to the authorizer service, aserto-go provides gRPC clients for Aserto's administrative services, allowing users to programmatically manage their aserto account.

An API client is created using client.New() which accepts the same connection options as authorizer.New().

// Client provides access to services only available usign gRPC.
type Client struct {
	// Directory provides methods for interacting with the Aserto user directory.
	// Use the Directory client to manage users, application, and roles.
	Directory dir.DirectoryClient

	// Policy provides read-only methods for listing and retrieving authorization policies defined in an Aserto account.
	Policy policy.PolicyClient

	// Info provides read-only access to system information and configuration.
	Info info.InfoClient
}

Similar to AuthorizerClient, the client interfaces are created from protocol buffer definitions and can be found in the "github.com/aserto-dev/go-grpc" package.

Client Package
DirectoryClient "github.com/aserto-dev/go-grpc/aserto/authorizer/directory/v1"
PolicyClient "github.com/aserto-dev/go-grpc/aserto/authorizer/policy/v1"
InfoClient "github.com/aserto-dev/go-grpc/aserto/common/info/v1"

Data structures used in these interfaces are defined in "github.com/aserto-dev/go-grpc/aserto/api/v1".

Documentation

Overview

The aserto package provides access to the Aserto authorization service.

Communication with the authorizer service is performed using an AuthorizerClient. The client can be used on its own to make authorization calls or, more commonly, it can be used to create server middleware.

Client

The AuthorizerClient interface has two implementations:

1. client/grpc/authorizer provides a client that communicates with the authorizer using gRPC.

2. client/http/authorizer provides a client that communicates with the authorizer over its REST HTTP endpoints.

Authorizer clients are created using authorizer.New().

Middleware

Authorization middleware provides integration of an AuthorizerClient into gRPC and HTTP servers.

1. middleware/grpc provides unary and stream server interceptors for gRPC servers.

2. middleware/http provides net/http middleware for integration with HTTP servers.

Jump to

Keyboard shortcuts

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