macaroon

package module
v0.0.0-...-e872c33 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2014 License: BSD-3-Clause Imports: 11 Imported by: 0

README

macaroon

-- import "github.com/rogpeppe/macaroon"

The macaroon package implements macaroons as described in the paper "Macaroons: Cookies with Contextual Caveats for Decentralized Authorization in the Cloud" (http://theory.stanford.edu/~ataly/Papers/macaroons.pdf)

Usage

type Caveat
type Caveat struct {
	Id       string
	Location string
}
type Macaroon
type Macaroon struct {
}

Macaroon holds a macaroon. See Fig. 7 of http://theory.stanford.edu/~ataly/Papers/macaroons.pdf for a description of the data contained within. Macaroons are mutable objects - use Clone as appropriate to avoid unwanted mutation.

func New
func New(rootKey []byte, id, loc string) (*Macaroon, error)

New returns a new macaroon with the given root key, identifier and location.

func (*Macaroon) AddFirstPartyCaveat
func (m *Macaroon) AddFirstPartyCaveat(caveatId string) error

AddFirstPartyCaveat adds a caveat that will be verified by the target service.

func (*Macaroon) AddThirdPartyCaveat
func (m *Macaroon) AddThirdPartyCaveat(rootKey []byte, caveatId string, loc string) error

AddThirdPartyCaveat adds a third-party caveat to the macaroon, using the given shared root key, caveat id and location hint. The caveat id should encode the root key in some way, either by encrypting it with a key known to the third party or by holding a reference to it stored in the third party's storage.

func (*Macaroon) Bind
func (m *Macaroon) Bind(rootSig []byte)

Bind prepares the macaroon for being used to discharge the macaroon with the given rootSig. This must be used before it is used in the discharges argument to Verify.

func (*Macaroon) Caveats
func (m *Macaroon) Caveats() []Caveat

Caveats returns the macaroon's caveats. This method will probably change, and it's important not to change the returned caveat.

func (*Macaroon) Clone
func (m *Macaroon) Clone() *Macaroon

Clone returns a copy of the receiving macaroon.

func (*Macaroon) Id
func (m *Macaroon) Id() string

Id returns the id of the macaroon. This can hold arbitrary information.

func (*Macaroon) Location
func (m *Macaroon) Location() string

Location returns the macaroon's location hint. This is not verified as part of the macaroon.

func (*Macaroon) MarshalJSON
func (m *Macaroon) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (*Macaroon) Signature
func (m *Macaroon) Signature() []byte

Signature returns the macaroon's signature.

func (*Macaroon) UnmarshalJSON
func (m *Macaroon) UnmarshalJSON(jsonData []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*Macaroon) Verify
func (m *Macaroon) Verify(rootKey []byte, check func(caveat string) error, discharges []*Macaroon) error

Verify verifies that the receiving macaroon is valid. The root key must be the same that the macaroon was originally minted with. The check function is called to verify each first-party caveat - it should return an error if the condition is not met.

The discharge macaroons should be provided in discharges.

Verify returns true if the verification succeeds; if returns (false, nil) if the verification fails, and (false, err) if the verification cannot be asserted (but may not be false).

TODO(rog) is there a possible DOS attack that can cause this function to infinitely recurse?

type Verifier
type Verifier interface {
	Verify(m *Macaroon, rootKey []byte) (bool, error)
}

bakery

-- import "github.com/rogpeppe/macaroon/bakery"

The bakery package layers on top of the macaroon package, providing a transport and storage-agnostic way of using macaroons to assert client capabilities.

Usage

var ErrNotFound = errors.New("item not found")
type Caveat
type Caveat struct {
	Location  string
	Condition string
}

Caveat represents a condition that must be true for a check to complete successfully. If Location is non-empty, the caveat must be discharged by a third party at the given location.

type CaveatIdDecoder
type CaveatIdDecoder interface {
	DecodeCaveatId(id string) (rootKey []byte, condition string, err error)
}

CaveatIdDecoder decodes caveat ids created by a CaveatIdEncoder.

type CaveatIdEncoder
type CaveatIdEncoder interface {
	EncodeCaveatId(caveat Caveat, rootKey []byte) (string, error)
}

CaveatIdEncoder can create caveat ids for third parties. It is left abstract to allow location-dependent caveat id creation.

type CaveatNotRecognizedError
type CaveatNotRecognizedError struct {
	Caveat string
}
func (*CaveatNotRecognizedError) Error
func (e *CaveatNotRecognizedError) Error() string
type Discharger
type Discharger struct {
	// Checker is used to check the caveat's condition.
	Checker ThirdPartyChecker

	// Decoder is used to decode the caveat id.
	Decoder CaveatIdDecoder

	// Factory is used to create the macaroon.
	// Note that *Service implements NewMacarooner.
	Factory NewMacarooner
}

A Discharger can be used to discharge third party caveats.

func (*Discharger) Discharge
func (d *Discharger) Discharge(id string) (*macaroon.Macaroon, error)

Discharge creates a macaroon that discharges the third party caveat with the given id. The id should have been created earlier with a matching CaveatIdEncoder. The condition implicit in the id is checked for validity using d.Checker, and then if valid, a new macaroon is minted which discharges the caveat, and can eventually be associated with a client request using AddClientMacaroon.

type FirstPartyChecker
type FirstPartyChecker interface {
	CheckFirstPartyCaveat(caveat string) error
}

FirstPartyChecker holds a function that checks first party caveats for validity.

If the caveat kind was not recognised, the checker should return ErrCaveatNotRecognised.

type FirstPartyCheckerFunc
type FirstPartyCheckerFunc func(caveat string) error
func (FirstPartyCheckerFunc) CheckFirstPartyCaveat
func (c FirstPartyCheckerFunc) CheckFirstPartyCaveat(caveat string) error
type NewMacarooner
type NewMacarooner interface {
	NewMacaroon(id string, rootKey []byte, capability string, caveats []Caveat) (*macaroon.Macaroon, error)
}

NewMacaroon mints a new macaroon with the given id, capability and caveats. If the id is empty, a random id will be used. If rootKey is nil, a random root key will be used.

If a client succeeds in discharging the returned macaroon, it can gain access to the given capability.

type NewServiceParams
type NewServiceParams struct {
	// Location will be set as the location of any macaroons
	// minted by the service.
	Location string

	// Store will be used to store macaroon
	// information locally. If it is nil,
	// an in-memory storage will be used.
	Store Storage

	// CaveatIdEncoder is used to create third-party caveats.
	CaveatIdEncoder CaveatIdEncoder
}

NewServiceParams holds the parameters for a NewService call.

type Request
type Request struct {
}

Request represents a request made to a service by a client. The request may be long-lived. It holds a set of macaroons that the client wishes to be taken into account.

Methods on a Request may be called concurrently with each other.

func (*Request) AddClientMacaroon
func (req *Request) AddClientMacaroon(m *macaroon.Macaroon)

AddClientMacaroon associates the given macaroon with the request. The macaroon will be taken into account when req.Check is called.

TODO(rog) provide a way of deleting client macaroons?

func (*Request) Check
func (req *Request) Check(capability string) error

Check checks that the client has the given capability. If the verification fails in a way which might be remediable, it returns a VerificationError that describes the error.

A capability represents a client capability. A client can gain a capability by presenting a valid, fully discharged macaroon that is associated with the capability.

type Service
type Service struct {
}

Service represents a service which can use macaroons to check authorization.

func NewService
func NewService(p NewServiceParams) *Service

NewService returns a new service that can mint new macaroons and store their associated root keys.

func (*Service) AddCaveat
func (svc *Service) AddCaveat(m *macaroon.Macaroon, cav Caveat) error

AddCaveat adds a caveat to the given macaroon.

If it's a third-party caveat, it uses the service's caveat-id encoder to create the id of the new caveat.

func (*Service) NewMacaroon
func (svc *Service) NewMacaroon(id string, rootKey []byte, capability string, caveats []Caveat) (*macaroon.Macaroon, error)

NewMacaroon implements NewMacarooner.NewMacaroon.

func (*Service) NewRequest
func (svc *Service) NewRequest(checker FirstPartyChecker) *Request

NewRequest returns a new client request object that uses checker to verify caveats.

func (*Service) Store
func (svc *Service) Store() Storage

Store returns the store used by the service.

type Storage
type Storage interface {
	// Put stores the item at the given location, overwriting
	// any item that might already be there.
	// TODO(rog) would it be better to lose the overwrite
	// semantics?
	Put(location string, item string) error

	// Get retrieves an item from the given location.
	// If the item is not there, it returns ErrNotFound.
	Get(location string) (item string, err error)

	// Del deletes the item from the given location.
	Del(location string) error
}

Storage defines storage for macaroons. Calling its methods concurrently is allowed.

func NewMemStorage
func NewMemStorage() Storage

NewMemStorage returns an implementation of Storage that stores all items in memory.

type ThirdPartyChecker
type ThirdPartyChecker interface {
	CheckThirdPartyCaveat(caveat string) ([]Caveat, error)
}

ThirdPartyChecker holds a function that checks third party caveats for validity. It the caveat is valid, it returns a nil error and optionally a slice of extra caveats that will be added to the discharge macaroon.

If the caveat kind was not recognised, the checker should return ErrCaveatNotRecognised.

type ThirdPartyCheckerFunc
type ThirdPartyCheckerFunc func(caveat string) ([]Caveat, error)
func (ThirdPartyCheckerFunc) CheckThirdPartyCaveat
func (c ThirdPartyCheckerFunc) CheckThirdPartyCaveat(caveat string) ([]Caveat, error)
type VerificationError
type VerificationError struct {
	RequiredCapability string
	Reason             error
}
func (*VerificationError) Error
func (e *VerificationError) Error() string

checkers

-- import "github.com/rogpeppe/macaroon/bakery/checkers"

The checkers package provides some standard caveat checkers and checker-combining functions.

Usage

var Std = Map{
	"time-before": bakery.FirstPartyCheckerFunc(timeBefore),
}
func FirstParty
func FirstParty(condition string) bakery.Caveat
func ParseCaveat
func ParseCaveat(cav string) (string, string, error)

ParseCaveat parses a caveat into an identifier, identifying the checker that should be used, and the argument to the checker (the rest of the string).

The identifier is taken from all the characters before the first space character.

func PushFirstPartyChecker
func PushFirstPartyChecker(c0, c1 bakery.FirstPartyChecker) bakery.FirstPartyChecker

PushFirstPartyChecker returns a checker that first uses c0 to check caveats, and falls back to using c1 if c0 returns bakery.ErrCaveatNotRecognized.

func ThirdParty
func ThirdParty(location, condition string) bakery.Caveat
func TimeBefore
func TimeBefore(t time.Time) bakery.Caveat
type Map
type Map map[string]bakery.FirstPartyCheckerFunc
func (Map) CheckFirstPartyCaveat
func (m Map) CheckFirstPartyCaveat(cav string) error

httpbakery

-- import "github.com/rogpeppe/macaroon/httpbakery"

The httpbakery package layers on top of the bakery package - it provides an HTTP-based implementation of a macaroon client and server.

Usage

func Do
func Do(c *http.Client, req *http.Request) (*http.Response, error)

Do makes an http request to the given client. If the request fails with a discharge-required error, any required discharge macaroons will be acquired, and the request will be repeated with those attached.

If c.Jar field is non-nil, the macaroons will be stored there and made available to subsequent requests.

func WriteDischargeRequiredError
func WriteDischargeRequiredError(w http.ResponseWriter, m *macaroon.Macaroon, originalErr error) error

WriteDischargeRequiredError writes a response to w that reports the given error and sends the given macaroon to the client, indicating that it should be discharged to allow the original request to be accepted.

If it returns an error, it will have written the http response anyway.

The cookie value is a base-64-encoded JSON serialization of the macaroon.

TODO(rog) consider an alternative approach - perhaps it would be better to include the macaroon directly in the response and leave it up to the client to add it to the cookies along with the discharge macaroons.

type KeyPair
type KeyPair struct {
}

KeyPair holds a public/private pair of keys.

func GenerateKey
func GenerateKey() (*KeyPair, error)

GenerateKey generates a new key pair.

type NewServiceParams
type NewServiceParams struct {
	// Location holds the location of the service.
	// Macaroons minted by the service will have this location.
	Location string

	// Store defines where macaroons are stored.
	Store bakery.Storage

	// Key holds the private/public key pair for
	// the service to use. If it is nil, a new key pair
	// will be generated.
	Key *KeyPair
}

NewServiceParams holds parameters for the NewService call.

type Service
type Service struct {
	*bakery.Service
}

Service represents a service that can use client-provided macaroons to authorize requests. It layers on top of *bakery.Service, providing http-based methods to create third-party caveats.

func NewService
func NewService(p NewServiceParams) (*Service, error)

NewService returns a new Service.

func (*Service) AddDischargeHandler
func (svc *Service) AddDischargeHandler(
	root string,
	mux *http.ServeMux,
	checker func(req *http.Request, cav string) ([]bakery.Caveat, error),
)

AddDischargeHandler handles adds handlers to the given ServeMux to service third party caveats.

The check function is used to check whether a client making the given request should be allowed a discharge for the given caveat. If it does not return an error, the caveat will be discharged, with any returned caveats also added to the discharge macaroon.

The name space served by DischargeHandler is as follows. All parameters can be provided either as URL attributes or form attributes. The result is always formatted as a JSON object.

POST /discharge

params:
	id: id of macaroon to discharge
	location: location of original macaroon (optional (?))
result:
	{
		Macaroon: macaroon in json format
		Error: string
	}

POST /create

params:
	condition: caveat condition to discharge
	rootkey: root key of discharge caveat
result:
	{
		CaveatID: string
		Error: string
	}

GET /publickey

result:
	public key of service
	expiry time of key
func (*Service) AddPublicKeyForLocation
func (svc *Service) AddPublicKeyForLocation(loc string, prefix bool, publicKey *[32]byte)

AddPublicKeyForLocation specifies that third party caveats for the given location will be encrypted with the given public key. If prefix is true, any locations with loc as a prefix will be also associated with the given key. The longest prefix match will be chosen. TODO(rog) perhaps string might be a better representation of public keys?

func (*Service) NewRequest
func (svc *Service) NewRequest(httpReq *http.Request, checker bakery.FirstPartyChecker) *bakery.Request

NewRequest returns a new request, converting cookies from the HTTP request into macaroons in the bakery request when they're found. Mmm.

Documentation

Overview

WARNING

The macaroon package is deprecated at this import path. Please use gopkg.in/macaroon.v1 instead.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Caveat

type Caveat struct {
	Id       string
	Location string
}

type Macaroon

type Macaroon struct {
	// contains filtered or unexported fields
}

Macaroon holds a macaroon. See Fig. 7 of http://theory.stanford.edu/~ataly/Papers/macaroons.pdf for a description of the data contained within. Macaroons are mutable objects - use Clone as appropriate to avoid unwanted mutation.

func New

func New(rootKey []byte, id, loc string) (*Macaroon, error)

New returns a new macaroon with the given root key, identifier and location.

func (*Macaroon) AddFirstPartyCaveat

func (m *Macaroon) AddFirstPartyCaveat(caveatId string) error

AddFirstPartyCaveat adds a caveat that will be verified by the target service.

func (*Macaroon) AddThirdPartyCaveat

func (m *Macaroon) AddThirdPartyCaveat(rootKey []byte, caveatId string, loc string) error

AddThirdPartyCaveat adds a third-party caveat to the macaroon, using the given shared root key, caveat id and location hint. The caveat id should encode the root key in some way, either by encrypting it with a key known to the third party or by holding a reference to it stored in the third party's storage.

func (*Macaroon) Bind

func (m *Macaroon) Bind(rootSig []byte)

Bind prepares the macaroon for being used to discharge the macaroon with the given rootSig. This must be used before it is used in the discharges argument to Verify.

func (*Macaroon) Caveats

func (m *Macaroon) Caveats() []Caveat

Caveats returns the macaroon's caveats. This method will probably change, and it's important not to change the returned caveat.

func (*Macaroon) Clone

func (m *Macaroon) Clone() *Macaroon

Clone returns a copy of the receiving macaroon.

func (*Macaroon) Id

func (m *Macaroon) Id() string

Id returns the id of the macaroon. This can hold arbitrary information.

func (*Macaroon) Location

func (m *Macaroon) Location() string

Location returns the macaroon's location hint. This is not verified as part of the macaroon.

func (*Macaroon) MarshalBinary

func (m *Macaroon) MarshalBinary() ([]byte, error)

MarshalBinary implements encoding.BinaryMarshaler.

func (*Macaroon) MarshalJSON

func (m *Macaroon) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (*Macaroon) Signature

func (m *Macaroon) Signature() []byte

Signature returns the macaroon's signature.

func (*Macaroon) UnmarshalBinary

func (m *Macaroon) UnmarshalBinary(data []byte) error

UnmarshalBinary implements encoding.BinaryUnmarshaler.

func (*Macaroon) UnmarshalJSON

func (m *Macaroon) UnmarshalJSON(jsonData []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*Macaroon) Verify

func (m *Macaroon) Verify(rootKey []byte, check func(caveat string) error, discharges []*Macaroon) error

Verify verifies that the receiving macaroon is valid. The root key must be the same that the macaroon was originally minted with. The check function is called to verify each first-party caveat - it should return an error if the condition is not met.

The discharge macaroons should be provided in discharges.

Verify returns true if the verification succeeds; if returns (false, nil) if the verification fails, and (false, err) if the verification cannot be asserted (but may not be false).

TODO(rog) is there a possible DOS attack that can cause this function to infinitely recurse?

type Verifier

type Verifier interface {
	Verify(m *Macaroon, rootKey []byte) (bool, error)
}

Directories

Path Synopsis
The bakery package layers on top of the macaroon package, providing a transport and storage-agnostic way of using macaroons to assert client capabilities.
The bakery package layers on top of the macaroon package, providing a transport and storage-agnostic way of using macaroons to assert client capabilities.
checkers
The checkers package provides some standard caveat checkers and checker-combining functions.
The checkers package provides some standard caveat checkers and checker-combining functions.
example
This example demonstrates three components: - A target service, representing a web server that wishes to use macaroons for authorization.
This example demonstrates three components: - A target service, representing a web server that wishes to use macaroons for authorization.
The httpbakery package layers on top of the bakery package - it provides an HTTP-based implementation of a macaroon client and server.
The httpbakery package layers on top of the bakery package - it provides an HTTP-based implementation of a macaroon client and server.

Jump to

Keyboard shortcuts

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