aserto

package module
v0.8.13 Latest Latest
Warning

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

Go to latest
Published: Sep 19, 2022 License: MIT Imports: 0 Imported by: 0

README

aserto-dev/aserto-go

ci Go Reference Go Report Card

Package aserto-go implements clients and middleware for the Aserto authorizer and supporting services.

Authorization requests are performed using an AuthorizerClient. A client can be used on its own to make authorization calls or, more commonly, it can be used to create server middleware.

Install

go get -u github.com/aserto-dev/aserto-go

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. authorizer/grpc provides a client that communicates with the authorizer using gRPC.

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

Create a new client using New() in either package.

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

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

The options below can be specified to override default behaviors:

WithAddr() - sets the server address and port. Default: "authorizer.prod.aserto.com:8443".

WithAPIKeyAuth() - sets an API key for authentication.

WithTokenAuth() - sets an OAuth2 token to be used for authentication.

WithTenantID() - sets the aserto tenant ID.

WithInsecure() - enables/disables TLS verification. Default: false.

WithCACertPath() - adds the specified PEM certificate file to the connection's list of trusted root CAs.

Connection Timeout

Connection timeout can be set on the specified context using context.WithTimeout. If no timeout is set on the context, the default connection timeout is 5 seconds. For example, to increase the timeout to 10 seconds:

ctx := context.Background()

authorizer, err := grpc.New(
	context.WithTimeout(ctx, time.Duration(10) * time.Second),
	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.

import (
	authz "github.com/aserto-dev/go-grpc-authz/aserto/authorizer/authorizer/v1"
	"github.com/aserto-dev/go-grpc/aserto/api/v1"
)

resp, err := authorizer.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 are created from an AuthorizerClient and a Policy with parameters that can be shared by all authorization calls.

// Policy holds global authorization options that apply to all requests.
type Policy struct {
	// ID is the ID of the aserto policy being queried for authorization.
	ID string

	// Path is the package name of the rego policy to evaluate.
	// If left empty, a policy mapper must be attached to the middleware to provide
	// the policy path from incoming messages.
	Path string

	// Decision 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. A default value can be set in Policy.Path when creating the middleware, but the path is often dependent on the details of the request being authorized.
  • Resource Context - Additional data sent to the authorizer as JSON.
Identity

Middlewares offer control over the identity used in authorization calls:

// Use the subject name "george@acmecorp".
middleware.Identity.Subject().ID("george@acmecorp.com")

// Use a JWT from the Authorization header.
middleware.Identity.JWT().FromHeader("Authorization")

// Use subject name from the "identity" metadata key in the request `Context`.
middleware.Identity.Subject().FromMetadata("identity")

// Read identity from the context value "user". Middleware infers the identity type from the value.
middleware.Identity.FromContext("user")

In addition, it is possible to provide custom logic to specify the callers identity. For example, in HTTP middleware:

middleware.Identity.Mapper(func(r *http.Request, identity middleware.Identity) {
	username := getUserFromRequest(r) // custom logic to get user identity

	identity.Subject().ID(username) // set it on the middleware
})

In all cases, if a value cannot be retrieved from the specified source (header, context, etc.), the authorization call checks for unauthenticated access.

Policy

The authorization policy's ID and the decision to be evaluated are specified when creating authorization Middleware, but the policy path is often derived from the URL or method being called.

By default, the policy path is derived from the URL path in HTTP middleware and the grpc.Method in gRPC middleware.

To provide custom logic, use middleware.WithPolicyPathMapper(). For example, in gRPC middleware:

middleware.WithPolicyPathMapper(func(ctx context.Context, req interface{}) string {
	path := getPolicyPath(ctx, req) // custom logic to retrieve a JWT token
	return path
})
Resource

A resource can be any structured data that the authorization policy uses to evaluate decisions. By default, middleware do not include a resource in authorization calls.

To add resource data, use Middleware.WithResourceMapper() to attach custom logic. For example, in HTTP middleware:

middleware.WithResourceMapper(func(r *http.Request) *structpb.Struct {
	return structFromBody(r.Body) // custom logic
})

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/grpc. It implements unary and stream gRPC server interceptors in its .Unary() and .Stream() methods.

import (
	"github.com/aserto-dev/aserto-go/middleware"
	grpcmw "github.com/aserto-dev/aserto-go/middleware/grpc"
	"google.golang.org/grpc"
)
...
middleware, err := grpcmw.New(
	client,
	middleware.Policy{
		ID: "<Policy ID>",
		Decision: "allowed",
	},
)

server := grpc.NewServer(
	grpc.UnaryInterceptor(middleware.Unary),
	grpc.StreamInterceptor(middleware.Stream),
)
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

	// ResourceMapper functions are used to extract structured data from incoming message.
	ResourceMapper func(context.Context, interface{}, map[string]interface{})
)

In addition to the general WithIdentityMapper, WithPolicyPathMapper, and WithResourceMapper, the gRPC middleware provides methods to help construct resource contexts from incoming messages.

WithResourceFromFields(fields ...string) selects a specified set of fields from the incoming message to be included in the authorization resource.

WithResourceFromMessageByPath(fieldsByPath map[string][]string, defaults ...string) is similar to WithResourceFromFields but can select different sets of fields depending on which service method is called.

WithResourceFromContextValue(ctxKey interface{}, field string) reads a value from the incoming request context and adds it as a field to the resource context.

Default Mappers

The default behavior of the gRPC middleware is:

  • Identity is pulled form the "authorization" metadata field (i.e. middleware.Identity.FromMetadata("authorization")).
  • Policy path is constructed from grpc.Method() with dots (.) replacing path delimiters (/).
  • No Resource Context is included in authorization calls by default.
HTTP Middleware

The HTTP middleware are available under the sub-package middleware/http.

Several flavors are implemented:

  • Standard net/http middleware is implemented in middleware/http/std.
  • Gin middleare is implemented in middleware/http/gin.

All middleware are constructed and configured in a similar way. They differ in the signature of their Handler() function, which is used to attach them to HTTP routes, and in the signatures of their mapper functions.

net/http Middleware
import (
	"github.com/aserto-dev/aserto-go/middleware"
	"github.com/aserto-dev/aserto-go/middleware/http/std"
)
...
mw := std.New(
	client,
	middleware.Policy{
		ID: "<Policy ID>",
		Decision: "allowed",
	},
)

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

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

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

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

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 WithIdentityFromHeader() to extract identity information from HTTP headers, and WithNoResourceContext() to omit a resource context from authorization calls.

Default Mappers

The default behavior of the HTTP middleware is:

  • Identity is retrieved from the "Authorization" HTTP Header, if present.
  • Policy path is retrieved from the request URL and method to form a path of the form 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.
  • Any path parameters defined using gorilla/mux are included in the resource context. For example, if the route is defined as "api/products/{id}" and the incoming request URL path is "api/products/123" then the resource context will be {"id": "123"}.
Gin Middleware

The gin middleware looks and behaves just like the net/http middleware with the following differnces:

  • Its Handler function is a gin.HandlerFunc which can be used with IRoutes.Use(...HandlerFunc).
  • Its mappers take *gin.Context instead of *http.Request:
      type (
      	StringMapper func(*gin.Context) string
      	StructMapper func(*gin.Context) *structpb.Struct
      )
    

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.

There are two top-level services, each with its own set of sub-services.

  1. client/authorizer defines a client for services run at the edge and used to serve authorization requests.
  2. client/tenant defines the control-plane services used to configure authorizers.

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

Edge Client
// Client provides access to Aserto edge services.
type Client struct {
	// Authorizer provides methods for performing authorization requests.
	Authorizer authorizer.AuthorizerClient

	// 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 methods for creating, listing, and deleting policy references.
	Policy policy.PolicyClient

	// Info provides read-only access to system information and configuration.
	Info info.InfoClient
}
Tenant Client
// Client provides access to the Aserto control service.
type Client struct {
	// Account provides methods for managing a customer account.
	Account account.AccountClient

	// Connections provides methods to create and manage connections.
	Connections connection.ConnectionClient

	// Onboarding provides methods to create tenants and invite users.
	Onboarding onboarding.OnboardingClient

	// Policy provides methods for creating, listing, and deleting policy references.
	Policy policy.PolicyClient

	// Profile provides methods for managing user invitations.
	Profile profile.ProfileClient

	// Provider provides methods for viewing the providers available to create connections.
	Provider provider.ProviderClient

	// SCC provides methods for interacting with a tenant's configured source-control repositories.
	SCC scc.SourceCodeCtlClient

	// Info provides methods for retrieving 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
AccountClient "github.com/aserto-dev/go-grpc/aserto/tenant/account/v1"
AuthorizerClient "github.com/aserto-dev/go-grpc-authz/aserto/authorizer/authorizer/v1"
ConnectionClient "github.com/aserto-dev/go-grpc/aserto/tenant/connection/v1"
DirectoryClient "github.com/aserto-dev/go-grpc/aserto/authorizer/directory/v1"
InfoClient "github.com/aserto-dev/go-grpc/aserto/common/info/v1"
OnboardingClient "github.com/aserto-dev/go-grpc/aserto/tenant/onboarding/v1"
PolicyClient "github.com/aserto-dev/go-grpc/aserto/authorizer/policy/v1"
ProfileClient "github.com/aserto-dev/go-grpc/aserto/tenant/profile/v1"
ProviderClient "github.com/aserto-dev/go-grpc/aserto/tenant/provider/v1"
SourceCodeCtlClient "github.com/aserto-dev/go-grpc/aserto/tenant/scc/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 authorizer and supporting service.

Authorization requests are performed using an AuthorizerClient. A 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. `authorizer/grpc` provides a client that communicates with the authorizer using gRPC.

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

Middleware

Two middleware implementations are available in subpackages:

1. middleware/grpc provides middleware for gRPC servers.

2. 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.

Other 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.

There are two top-level services, each with its own set of sub-services.

1. `client/authorizer` defines a client for services run at the edge and used to serve authorization requests. 2. `client/tenant` defines the control-plane services used to configure authorizers.

Directories

Path Synopsis
Package authorizer provides functions for creating an AuthorizerClient.
Package authorizer provides functions for creating an AuthorizerClient.
grpc
Package grpc is used to create an AuthorizerClient that communicates with the authorizer using gRPC.
Package grpc is used to create an AuthorizerClient that communicates with the authorizer using gRPC.
http
Package http is used to create an AuthorizerClient that communicates with the authorizer using HTTP.
Package http is used to create an AuthorizerClient that communicates with the authorizer using HTTP.
Package client provides communication with the Aserto services.
Package client provides communication with the Aserto services.
examples
internal
Package middleware provides components that integrate Aserto authorization to gRPC or HTTP servers.
Package middleware provides components that integrate Aserto authorization to gRPC or HTTP servers.
grpc
Package grpc provides authorization middleware for gRPC servers.
Package grpc provides authorization middleware for gRPC servers.
http/std
Package std provides authorization middleware for HTTP servers built on top of the standard net/http.
Package std provides authorization middleware for HTTP servers built on top of the standard net/http.

Jump to

Keyboard shortcuts

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