attest

package module
v0.10.2 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2022 License: MIT Imports: 15 Imported by: 0

README

pkg.go.dev

About

macos-device-attestation is a library to help build a macOS device attestation service. An on-device client can use this library to attest to a server using this library that it's running as root on the particular device.

How It Works

At a high level, a server creates an attest.AttestationService and mounts it's PlaceHandler and FileStoreHandler at URLs accessible by the client. When a client requests attestation, the server uses a transport.Transport (see below) to securely place a token only readable by root on the client and tells the client where to read it from.

The server can protect any other URLs with the AttestationService's Middleware (or built-in JSONMiddleware helper). The client sends the token in the Authorization header, and the Middleware authenticates the token and places the identifier in the http.Request's context (with key attest.ContextKeyIdentifier).

At a lower level, attest.AttestationService is backed by several interfaces:

  • tokenstore.TokenStore: generates and authenticates tokens. Currently there are two implementations:
    • mem.TokenStore: in-memory, bounded cache storage of tokens
    • jwt.TokenStore: generates stateless, expirable JWT tokens
  • filestore.FileStore: stores and retreives files for use by a transport.Transport. Currently there is one implementation:
    • mem.FileStore: in-memory, bounded, auto-expiring cache storage of files
  • transport.Transport: places a secret on a device. Currently there is one implementation:
    • mdm.Transport: uses an mdm.MDM (see below) to place the secret on a device via an InstallEnterpriseApplication command
    • A transport.Transport can optionally implement an attest.Transformer interface that transforms client identifiers to server identifiers. This is used by mdm.Transport to transform client-sent serial numbers to MDM server UDIDs

mdm.MDM is itself an interface that currently has one implementation:

  • micromdm.MDM: uses MicroMDM's API

This library is meant to be extensible. Some examples of extending it:

  • Use the token long-term or as a stepping-stone to more advanced PKI
  • Implement an mdm.MDM for your MDM (assuming it has an API!)
  • Implement a non-MDM transport.Transport. e.g. with SSH. Make sure your Transport can absolutely target the correct device and the secret stays secure!
  • Create a filestore.FileStore that can be shared by multiple servers

PRs are welcome for implementations that are useful for a wide audience!

Security

macOS device serial numbers and UDIDs can be spoofed. To use an MDM in the chain of trust, you must ensure only authenticated devices are allowed to enroll in your MDM server. Otherwise a bad actor could possibly spoof the serial number and UDID of another device to obtain a token for it.

Usage

See the server and client examples.

Issues

If you have any issues or questions create an issue.

Documentation

Index

Constants

View Source
const StatusCodeSkip int = -1

StatusCodeSkip is returned by a ReturnHandlerFunc to indicate the ResponseWriter should not be written to

Variables

View Source
var ErrInvalidIdentifier = errors.New("invalid identifier")

ErErrInvalidIdentifier is returned by a Transformer if the client identifier is invalid

Functions

This section is empty.

Types

type AttestationService

type AttestationService struct {
	tokenstore.TokenStore
	transport.Transport
	filestore.FileStore
	*log.Logger
}

AttestationService is an HTTP service to allow a macOS client to attest that it has root access on a device with a particular identifier

func New

func New(tokenStore tokenstore.TokenStore, transport transport.Transport, fileStore filestore.FileStore, logger *log.Logger) *AttestationService

New returns a new AttestationService

func (*AttestationService) FileStoreHandler

func (s *AttestationService) FileStoreHandler() http.Handler

FileStoreHandler is a file handler. If the handler is not mounted at "/", then it should be wrapped in http.StripPrefix so the handler sees the request rooted at /

func (*AttestationService) JSONMiddleware

func (s *AttestationService) JSONMiddleware(next http.Handler) http.Handler

JSONMiddleware is a wrapper for Middleware that returns errors encountered back to the client in JSON format. e.g. {"code":401,"description":"Bad Request"}

func (*AttestationService) Middleware

func (s *AttestationService) Middleware(next http.Handler) ReturnHandlerFunc

Middleware is a middleware that checks that a valid attestation token has been sent in the Authorization header, and sets the corresponding identifier in the request's context. Middleware returns a ReturnHandlerFunc and is intended to be wrapped by an http.Handler that will handle the returned status code and error. See ReturnHandlerFunc for more information. JSONMiddleware is a pre-built handler that marshals the code and error as JSON.

func (*AttestationService) PlaceHandler

func (s *AttestationService) PlaceHandler() http.Handler

PlaceHandler is a token placing http.Handler. PlaceHandler should be mounted to a URL that's called by an attestation client

type ContextKey

type ContextKey int
const ContextKeyIdentifier ContextKey = iota

ContextKeyIdentifier is used to retrieve the identifier from an http.Request's context

type ReturnHandlerFunc

type ReturnHandlerFunc func(w http.ResponseWriter, r *http.Request) (int, interface{})

ReturnHandlerFunc returns an HTTP status code and body for the given request. If the returned code is StatusCodeSkip, the ResponseWriter should not be written to by the caller

type Transformer added in v0.10.0

type Transformer interface {
	// Transform transforms identifier into another one. If the identifier is invalid, ErrInvalidIdentifier is returned
	Transform(identifier string) (string, error)
}

Transformer is an optional interface that a Transport can implement to transform a client-given identifier to a server-provided one. The mdm Transport uses this to transform serial numbers given by the client to MDM UDIDs

Directories

Path Synopsis
examples
mem
mdm
jwt
mem
mdm

Jump to

Keyboard shortcuts

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