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


The Bakery type is probably where you want to start. It encapsulates a Checker type, which performs checking of operations, and an Oven type, which encapsulates the actual details of the macaroon encoding conventions.

Most other types and functions are designed either to plug into one of the above types (the various Authorizer implementations, for example), or to expose some independent functionality that's potentially useful (Discharge, for example).

The rest of this introduction introduces some of the concepts used by the bakery package.

Identity and entities

An Identity represents some authenticated user (or agent), usually the client in a network protocol. An identity can be authenticated by an external identity server (with a third party macaroon caveat) or by locally provided information such as a username and password.

The Checker type is not responsible for determining identity - that functionality is represented by the IdentityClient interface.

The Checker uses identities to decide whether something should be allowed or not - the Authorizer interface is used to ask whether a given identity should be allowed to perform some set of operations.


An operation defines some requested action on an entity. For example, if file system server defines an entity for every file in the server, an operation to read a file might look like:

		Entity: "/foo",
		Action: "write",

The exact set of entities and actions is up to the caller, but should be kept stable over time because authorization tokens will contain these names.

To authorize some request on behalf of a remote user, first find out what operations that request needs to perform. For example, if the user tries to delete a file, the entity might be the path to the file's directory and the action might be "write". It may often be possible to determine the operations required by a request without reference to anything external, when the request itself contains all the necessary information.

The LoginOp operation is special - any macaroon associated with this operation is treated as a bearer of identity information. If two valid LoginOp macaroons are presented, only the first one will be used for identity.


The Authorizer interface is responsible for determining whether a given authenticated identity is authorized to perform a set of operations. This is used when the macaroons provided to Auth are not sufficient to authorize the operations themselves.


A "capability" is represented by a macaroon that's associated with one or more operations, and grants the capability to perform all those operations. The AllowCapability method reports whether a capability is allowed. It takes into account any authenticated identity and any other capabilities provided.

Third party caveats

Sometimes authorization will only be granted if a third party caveat is discharged. This will happen when an IdentityClient or Authorizer returns a third party caveat.

When this happens, a DischargeRequiredError will be returned containing the caveats and the operations required. The caller is responsible for creating a macaroon with those caveats associated with those operations and for passing that macaroon to the client to discharge.



View Source
const KeyLen = 32

KeyLen is the byte length of the Ed25519 public and private keys used for caveat id encryption.

View Source
const NonceLen = 24

NonceLen is the byte length of the nonce values used for caveat id encryption.


View Source
var (
	// ErrNotFound is returned by Store.Get implementations
	// to signal that an id has not been found.
	ErrNotFound = errgo.New("not found")

	// ErrPermissionDenied is returned from AuthChecker when
	// permission has been denied.
	ErrPermissionDenied = errgo.New("permission denied")
View Source
var NoOp = Op{}

NoOp holds the empty operation, signifying no authorized operation. This is always considered to be authorized. See OpsAuthorizer for one place that it's used.


func DischargeAll

func DischargeAll(
	ctx context.Context,
	m *Macaroon,
	getDischarge func(ctx context.Context, cav macaroon.Caveat, encryptedCaveat []byte) (*Macaroon, error),
) (macaroon.Slice, error)

DischargeAll gathers discharge macaroons for all the third party caveats in m (and any subsequent caveats required by those) using getDischarge to acquire each discharge macaroon. It returns a slice with m as the first element, followed by all the discharge macaroons. All the discharge macaroons will be bound to the primary macaroon.

The getDischarge function is passed the caveat to be discharged; encryptedCaveat will be passed the external caveat payload found in m, if any.

func DischargeAllWithKey

func DischargeAllWithKey(
	ctx context.Context,
	m *Macaroon,
	getDischarge func(ctx context.Context, cav macaroon.Caveat, encodedCaveat []byte) (*Macaroon, error),
	localKey *KeyPair,
) (macaroon.Slice, error)

DischargeAllWithKey is like DischargeAll except that the localKey parameter may optionally hold the key of the client, in which case it will be used to discharge any third party caveats with the special location "local". In this case, the caveat itself must be "true". This can be used be a server to ask a client to prove ownership of the private key.

When localKey is nil, DischargeAllWithKey is exactly the same as DischargeAll.

func IsDischargeRequiredError

func IsDischargeRequiredError(err error) bool

func LocalThirdPartyCaveat

func LocalThirdPartyCaveat(key *PublicKey, version Version) checkers.Caveat

LocalThirdPartyCaveat returns a third-party caveat that, when added to a macaroon with AddCaveat, results in a caveat with the location "local", encrypted with the given public key. This can be automatically discharged by DischargeAllWithKey.

func MacaroonVersion

func MacaroonVersion(v Version) macaroon.Version

MacaroonVersion returns the macaroon version that should be used with the given bakery Version.


type AuthChecker

type AuthChecker struct {
	// Checker is used to check first party caveats.
	// contains filtered or unexported fields

AuthChecker authorizes operations with respect to a user's request.

func (*AuthChecker) Allow

func (a *AuthChecker) Allow(ctx context.Context, ops ...Op) (*AuthInfo, error)

Allow checks that the authorizer's request is authorized to perform all the given operations.

If all the operations are allowed, an AuthInfo is returned holding details of the decision.

If an operation was not allowed, an error will be returned which may be *DischargeRequiredError holding the operations that remain to be authorized in order to allow authorization to proceed.

func (*AuthChecker) Allowed

func (a *AuthChecker) Allowed(ctx context.Context) (*AuthInfo, error)

Allowed returns an AuthInfo that provides information on all operations directly authorized by the macaroons provided to Checker.Auth. Note that this does not include operations that would be indirectly allowed via the OpAuthorizer.

Allowed returns an error only when there is an underlying storage failure, not when operations are not authorized.

func (*AuthChecker) Macaroons

func (a *AuthChecker) Macaroons() []macaroon.Slice

Macaroons returns the macaroons that were passed to Checker.Auth when creating the AuthChecker.

type AuthInfo

type AuthInfo struct {
	// Macaroons holds all the macaroons that were
	// passed to Auth.
	Macaroons []macaroon.Slice

	// Used records which macaroons were used in the
	// authorization decision. It holds one element for
	// each element of Macaroons. Macaroons that
	// were invalid or unnecessary will have a false entry.
	Used []bool

	// OpIndexes holds the index of each macaroon
	// that was used to authorize an operation.
	OpIndexes map[Op]int

AuthInfo information about an authorization decision.

func (*AuthInfo) Conditions

func (a *AuthInfo) Conditions() []string

Conditions returns the first party caveat caveat conditions hat apply to the given AuthInfo. This can be used to apply appropriate caveats to capability macaroons granted via a Checker.Allow call.

type Bakery

type Bakery struct {
	Oven    *Oven
	Checker *Checker

Bakery is a convenience type that contains both an Oven and a Checker.

func New

func New(p BakeryParams) *Bakery

New returns a new Bakery instance which combines an Oven with a Checker for the convenience of callers that wish to use both together.

type BakeryParams

type BakeryParams struct {
	// Logger is used to send log messages. If it is nil,
	// DefaultLogger("bakery") will be used.
	// will be used for logging.
	Logger Logger

	// Checker holds the checker used to check first party caveats.
	// If this is nil, New will use checkers.New(nil).
	Checker FirstPartyCaveatChecker

	// RootKeyStore holds the root key store to use. If you need to
	// use a different root key store for different operations,
	// you'll need to pass a RootKeyStoreForOps value to NewOven
	// directly.
	// If this is nil, New will use NewMemRootKeyStore().
	// Note that that is almost certain insufficient for production services
	// that are spread across multiple instances or that need
	// to persist keys across restarts.
	RootKeyStore RootKeyStore

	// Locator is used to find out information on third parties when
	// adding third party caveats. If this is nil, no non-local third
	// party caveats can be added.
	Locator ThirdPartyLocator

	// Key holds the private key of the oven. If this is nil,
	// no third party caveats may be added.
	Key *KeyPair

	// OpsAuthorizer is used to check whether operations are authorized
	// by some other already-authorized operation. If it is nil,
	// NewChecker will assume no operation is authorized by any
	// operation except itself.
	OpsAuthorizer OpsAuthorizer

	// Location holds the location to use when creating new macaroons.
	Location string

	// LegacyMacaroonOp holds the operation to associate with old
	// macaroons that don't have associated operations.
	// If this is empty, legacy macaroons will not be associated
	// with any operations.
	LegacyMacaroonOp Op

BakeryParams holds a selection of parameters for the Oven and the Checker created by New.

For more fine-grained control of parameters, create the Oven or Checker directly.

The zero value is OK to use, but won't allow any authentication or third party caveats to be added.

type Checker

type Checker struct {
	// contains filtered or unexported fields

Checker wraps a FirstPartyCaveatChecker and adds authentication and authorization checks.

It uses macaroons as authorization tokens but it is not itself responsible for creating the macaroons - see the Oven type (TODO) for one way of doing that.

func NewChecker

func NewChecker(p CheckerParams) *Checker

NewChecker returns a new Checker using the given parameters.

func (*Checker) Auth

func (c *Checker) Auth(mss ...macaroon.Slice) *AuthChecker

Auth makes a new AuthChecker instance using the given macaroons to inform authorization decisions.

type CheckerParams

type CheckerParams struct {
	// Checker is used to check first party caveats when authorizing.
	// If this is nil NewChecker will use checkers.New(nil).
	Checker FirstPartyCaveatChecker

	// OpsAuthorizer is used to check whether operations are authorized
	// by some other already-authorized operation. If it is nil,
	// NewChecker will assume no operation is authorized by any
	// operation except itself.
	OpsAuthorizer OpsAuthorizer

	// MacaroonVerifier is used to verify macaroons.
	MacaroonVerifier MacaroonVerifier

	// Logger is used to log checker operations. If it is nil,
	// DefaultLogger("bakery") will be used.
	Logger Logger

CheckerParams holds parameters for NewChecker.

type DischargeParams

type DischargeParams struct {
	// Id holds the id to give to the discharge macaroon.
	// If Caveat is empty, then the id also holds the
	// encrypted third party caveat.
	Id []byte

	// Caveat holds the encrypted third party caveat. If this
	// is nil, Id will be used.
	Caveat []byte

	// Key holds the key to use to decrypt the third party
	// caveat information and to encrypt any additional
	// third party caveats returned by the caveat checker.
	Key *KeyPair

	// Checker is used to check the third party caveat,
	// and may also return further caveats to be added to
	// the discharge macaroon.
	Checker ThirdPartyCaveatChecker

	// Locator is used to information on third parties
	// referred to by third party caveats returned by the Checker.
	Locator ThirdPartyLocator

DischargeParams holds parameters for a Discharge call.

type DischargeRequiredError

type DischargeRequiredError struct {
	// Message holds some reason why the authorization was denied.
	// TODO this is insufficient (and maybe unnecessary) because we
	// can have multiple errors.
	Message string

	// Ops holds all the operations that were not authorized.
	// If Ops contains a single LoginOp member, the macaroon
	// should be treated as an login token. Login tokens (also
	// known as authentication macaroons) usually have a longer
	// life span than other macaroons.
	Ops []Op

	// Caveats holds the caveats that must be added
	// to macaroons that authorize the above operations.
	Caveats []checkers.Caveat

	// ForAuthentication holds whether the macaroon holding
	// the discharges will be used for authentication, and hence
	// should have wider scope and longer lifetime.
	// The bakery package never sets this field, but bakery/identchecker
	// uses it.
	ForAuthentication bool

DischargeRequiredError is returned when authorization has failed and a discharged macaroon might fix it.

A caller should grant the user the ability to authorize by minting a macaroon associated with Ops (see MacaroonStore.MacaroonIdInfo for how the associated operations are retrieved) and adding Caveats. If the user succeeds in discharging the caveats, the authorization will be granted.

func (*DischargeRequiredError) Error

func (e *DischargeRequiredError) Error() string

type FirstPartyCaveatChecker

type FirstPartyCaveatChecker interface {
	// CheckFirstPartyCaveat checks that the given caveat condition
	// is valid with respect to the given context information.
	CheckFirstPartyCaveat(ctx context.Context, caveat string) error

	// Namespace returns the namespace associated with the
	// caveat checker.
	Namespace() *checkers.Namespace

FirstPartyCaveatChecker is used to check first party caveats for validity with respect to information in the provided context.

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

type Key

type Key [KeyLen]byte

Key is a 256-bit Ed25519 key.

func (Key) MarshalBinary

func (k Key) MarshalBinary() ([]byte, error)

MarshalBinary implements encoding.BinaryMarshaler.MarshalBinary.

func (Key) MarshalText

func (k Key) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.MarshalText.

func (Key) String

func (k Key) String() string

String returns the base64 representation of the key.

func (*Key) UnmarshalBinary

func (k *Key) UnmarshalBinary(data []byte) error

UnmarshalBinary implements encoding.BinaryUnmarshaler.UnmarshalBinary.

func (*Key) UnmarshalText

func (k *Key) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.UnmarshalText.

type KeyPair

type KeyPair struct {
	Public  PublicKey  `json:"public"`
	Private PrivateKey `json:"private"`

KeyPair holds a public/private pair of keys.

func GenerateKey

func GenerateKey() (*KeyPair, error)

GenerateKey generates a new key pair.

func MustGenerateKey

func MustGenerateKey() *KeyPair

MustGenerateKey is like GenerateKey but panics if GenerateKey returns an error - useful in tests.

func (*KeyPair) String

func (key *KeyPair) String() string

String implements the fmt.Stringer interface by returning the base64 representation of the public key part of key.

func (*KeyPair) UnmarshalJSON

func (k *KeyPair) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*KeyPair) UnmarshalYAML

func (k *KeyPair) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML implements yaml.Unmarshaler.

type Logger

type Logger interface {
	Infof(ctx context.Context, f string, args ...interface{})
	Debugf(ctx context.Context, f string, args ...interface{})

Logger is used by the bakery to log informational messages about bakery operations.

func DefaultLogger

func DefaultLogger(name string) Logger

DefaultLogger returns a Logger instance that uses to log messages using the given logger name.

type Macaroon

type Macaroon struct {
	// contains filtered or unexported fields

Macaroon represents an undischarged macaroon along with its first party caveat namespace and associated third party caveat information which should be passed to the third party when discharging a caveat.

func Discharge

func Discharge(ctx context.Context, p DischargeParams) (*Macaroon, error)

Discharge creates a macaroon to discharges a third party caveat. The given parameters specify the caveat and how it should be checked/

The condition implicit in the caveat is checked for validity using p.Checker. If it is valid, a new macaroon is returned which discharges the caveat.

The macaroon is created with a version derived from the version that was used to encode the id.

func NewLegacyMacaroon

func NewLegacyMacaroon(m *macaroon.Macaroon) (*Macaroon, error)

NewLegacyMacaroon returns a new macaroon holding m. This should only be used when there's no alternative (for example when m has been unmarshaled from some alternative format).

func NewMacaroon

func NewMacaroon(rootKey, id []byte, location string, version Version, ns *checkers.Namespace) (*Macaroon, error)

NewMacaroon creates and returns a new macaroon with the given root key, id and location. If the version is more than the latest known version, the latest known version will be used. The namespace is that of the service creating it.

func (*Macaroon) AddCaveat

func (m *Macaroon) AddCaveat(ctx context.Context, cav checkers.Caveat, key *KeyPair, loc ThirdPartyLocator) error

AddCaveat adds a caveat to the given macaroon.

If it's a third-party caveat, it encrypts it using the given key pair and by looking up the location using the given locator. If it's a first party cavat, key and loc are unused.

As a special case, if the caveat's Location field has the prefix "local " the caveat is added as a client self-discharge caveat using the public key base64-encoded in the rest of the location. In this case, the Condition field must be empty. The resulting third-party caveat will encode the condition "true" encrypted with that public key. See LocalThirdPartyCaveat for a way of creating such caveats.

func (*Macaroon) AddCaveats

func (m *Macaroon) AddCaveats(ctx context.Context, cavs []checkers.Caveat, key *KeyPair, loc ThirdPartyLocator) error

AddCaveats is a convenienced method that calls m.AddCaveat for each caveat in cavs.

func (*Macaroon) Clone

func (m *Macaroon) Clone() *Macaroon

Clone returns a copy of the macaroon. Note that the the new macaroon's namespace still points to the same underlying Namespace - copying the macaroon does not make a copy of the namespace.

func (*Macaroon) M

func (m *Macaroon) M() *macaroon.Macaroon

M returns the underlying macaroon held within m.

func (*Macaroon) MarshalJSON

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

MarshalJSON implements json.Marshaler by marshaling the macaroon into the original macaroon format if the version is earlier than Version3.

func (*Macaroon) Namespace

func (m *Macaroon) Namespace() *checkers.Namespace

Namespace returns the first party caveat namespace of the macaroon.

func (*Macaroon) UnmarshalJSON

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

UnmarshalJSON implements json.Unmarshaler by unmarshaling in a backwardly compatible way - if provided with a previous macaroon version, it will unmarshal that too.

func (*Macaroon) Version

func (m *Macaroon) Version() Version

Version returns the bakery version of the first party that created the macaroon.

type MacaroonVerifier

type MacaroonVerifier interface {
	// VerifyMacaroon verifies the signature of the given macaroon and returns
	// information on its associated operations, and all the first party
	// caveat conditions that need to be checked.
	// This method should not check first party caveats itself.
	// It should return a *VerificationError if the error occurred
	// because the macaroon signature failed or the root key
	// was not found - any other error will be treated as fatal
	// by Checker and cause authorization to terminate.
	VerifyMacaroon(ctx context.Context, ms macaroon.Slice) ([]Op, []string, error)

MacaroonVerifier verifies macaroons and returns the operations and caveats they're associated with.

type Op

type Op struct {
	// Entity holds the name of the entity to be authorized.
	// Entity names should not contain spaces and should
	// not start with the prefix "login" or "multi-" (conventionally,
	// entity names will be prefixed with the entity type followed
	// by a hyphen.
	Entity string

	// Action holds the action to perform on the entity, such as "read"
	// or "delete". It is up to the service using a checker to define
	// a set of operations and keep them consistent over time.
	Action string

Op holds an entity and action to be authorized on that entity.

func CanonicalOps

func CanonicalOps(ops []Op) []Op

CanonicalOps returns the given operations slice sorted with duplicates removed.

type OpsAuthorizer

type OpsAuthorizer interface {
	// AuthorizeOp reports which elements of queryOps are authorized by
	// authorizedOp. On return, each element of the slice should represent
	// whether the respective element in queryOps has been authorized.
	// An empty returned slice indicates that no operations are authorized.
	// AuthorizeOps may also return third party caveats that apply to
	// the authorized operations. Access will only be authorized when
	// those caveats are discharged by the client.
	// When not all operations can be authorized with the macaroons
	// supplied to Checker.Auth, the checker will call AuthorizeOps
	// with NoOp, because some operations might be authorized
	// regardless of authority. NoOp will always be the last
	// operation queried within any given Allow call.
	// AuthorizeOps should only return an error if authorization cannot be checked
	// (for example because of a database access failure), not because
	// authorization was denied.
	AuthorizeOps(ctx context.Context, authorizedOp Op, queryOps []Op) ([]bool, []checkers.Caveat, error)

OpsAuthorizer is used to check whether an operation authorizes some other operation. For example, a macaroon with an operation allowing general access to a service might also grant access to a more specific operation.

type Oven

type Oven struct {
	// contains filtered or unexported fields

Oven bakes macaroons. They emerge sweet and delicious and ready for use in a Checker.

All macaroons are associated with one or more operations (see the Op type) which define the capabilities of the macaroon.

There is one special operation, "login" (defined by LoginOp) which grants the capability to speak for a particular user. The login capability will never be mixed with other capabilities.

It is up to the caller to decide on semantics for other operations.

func NewOven

func NewOven(p OvenParams) *Oven

NewOven returns a new oven using the given parameters.

func (*Oven) AddCaveat

func (o *Oven) AddCaveat(ctx context.Context, m *Macaroon, cav checkers.Caveat) error

AddCaveat adds a caveat to the given macaroon.

func (*Oven) AddCaveats

func (o *Oven) AddCaveats(ctx context.Context, m *Macaroon, caveats []checkers.Caveat) error

AddCaveats adds all the caveats to the given macaroon.

func (*Oven) Key

func (o *Oven) Key() *KeyPair

Key returns the oven's private/public key par.

func (*Oven) Locator

func (o *Oven) Locator() ThirdPartyLocator

Locator returns the third party locator that the oven was created with.

func (*Oven) NewMacaroon

func (o *Oven) NewMacaroon(ctx context.Context, version Version, caveats []checkers.Caveat, ops ...Op) (*Macaroon, error)

NewMacaroon takes a macaroon with the given version from the oven, associates it with the given operations and attaches the given caveats. There must be at least one operation specified.

func (*Oven) VerifyMacaroon

func (o *Oven) VerifyMacaroon(ctx context.Context, ms macaroon.Slice) (ops []Op, conditions []string, err error)

VerifyMacaroon implements MacaroonVerifier.VerifyMacaroon, making Oven an instance of MacaroonVerifier.

For macaroons minted with previous bakery versions, it always returns a single LoginOp operation.

type OvenParams

type OvenParams struct {
	// Namespace holds the namespace to use when adding first party caveats.
	// If this is nil, checkers.New(nil).Namespace will be used.
	Namespace *checkers.Namespace

	// RootKeyStoreForEntity returns the macaroon storage to be
	// used for root keys associated with macaroons created
	// wth NewMacaroon.
	// If this is nil, NewMemRootKeyStore will be used to create
	// a new store to be used for all entities.
	RootKeyStoreForOps func(ops []Op) RootKeyStore

	// Key holds the private key pair used to encrypt third party caveats.
	// If it is nil, no third party caveats can be created.
	Key *KeyPair

	// Location holds the location that will be associated with new macaroons
	// (as returned by Macaroon.Location).
	Location string

	// Locator is used to find out information on third parties when
	// adding third party caveats. If this is nil, no non-local third
	// party caveats can be added.
	Locator ThirdPartyLocator

	// LegacyMacaroonOp holds the operation to associate with old
	// macaroons that don't have associated operations.
	// If this is empty, legacy macaroons will not be associated
	// with any operations.
	LegacyMacaroonOp Op

type PrivateKey

type PrivateKey struct {

PrivateKey is a 256-bit Ed25519 private key.

type PublicKey

type PublicKey struct {

PublicKey is a 256-bit Ed25519 public key.

type RootKeyStore

type RootKeyStore interface {
	// Get returns the root key for the given id.
	// If the item is not there, it returns ErrNotFound.
	Get(ctx context.Context, id []byte) ([]byte, error)

	// RootKey returns the root key to be used for making a new
	// macaroon, and an id that can be used to look it up later with
	// the Get method.
	// Note that the root keys should remain available for as long
	// as the macaroons using them are valid.
	// Note that there is no need for it to return a new root key
	// for every call - keys may be reused, although some key
	// cycling is over time is advisable.
	RootKey(ctx context.Context) (rootKey []byte, id []byte, err error)

RootKeyStore defines store for macaroon root keys.

func NewMemRootKeyStore

func NewMemRootKeyStore() RootKeyStore

NewMemRootKeyStore returns an implementation of Store that generates a single key and always returns that from RootKey. The same id ("0") is always used.

type Slice

type Slice []*Macaroon

Slice holds a slice of unbound macaroons.

func (Slice) Bind

func (s Slice) Bind() macaroon.Slice

Bind prepares the macaroon slice for use in a request. This must be done before presenting the macaroons to a service for use as authorization tokens. The result will only be valid if s contains discharge macaroons for all third party caveats.

All the macaroons in the returned slice will be copies of this in s, not references.

func (Slice) DischargeAll

func (ms Slice) DischargeAll(ctx context.Context, getDischarge func(ctx context.Context, cav macaroon.Caveat, encryptedCaveat []byte) (*Macaroon, error), localKey *KeyPair) (Slice, error)

DischargeAll discharges all the third party caveats in the slice for which discharge macaroons are not already present, using getDischarge to acquire the discharge macaroons. It always returns the slice with any acquired discharge macaroons added, even on error. It returns an error if all the discharges could not be acquired.

Note that this differs from DischargeAll in that it can be given several existing discharges, and that the resulting discharges are not bound to the primary, so it's still possible to add caveats and reacquire expired discharges without reacquiring the primary macaroon.

func (Slice) Purge

func (ms Slice) Purge(t time.Time) Slice

Purge returns a new slice holding all macaroons in s that expire after the given time.

type ThirdPartyCaveatChecker

type ThirdPartyCaveatChecker interface {
	CheckThirdPartyCaveat(ctx context.Context, info *ThirdPartyCaveatInfo) ([]checkers.Caveat, error)

ThirdPartyCaveatChecker holds a function that checks third party caveats for validity. If the caveat is valid, it returns a nil error and optionally a slice of extra caveats that will be added to the discharge macaroon. The caveatId parameter holds the still-encoded id of the caveat.

If the caveat kind was not recognised, the checker should return an error with a ErrCaveatNotRecognized cause.

type ThirdPartyCaveatCheckerFunc

type ThirdPartyCaveatCheckerFunc func(context.Context, *ThirdPartyCaveatInfo) ([]checkers.Caveat, error)

ThirdPartyCaveatCheckerFunc implements ThirdPartyCaveatChecker by calling a function.

func (ThirdPartyCaveatCheckerFunc) CheckThirdPartyCaveat

func (c ThirdPartyCaveatCheckerFunc) CheckThirdPartyCaveat(ctx context.Context, info *ThirdPartyCaveatInfo) ([]checkers.Caveat, error)

CheckThirdPartyCaveat implements ThirdPartyCaveatChecker.CheckThirdPartyCaveat by calling the receiver with the given arguments

type ThirdPartyCaveatInfo

type ThirdPartyCaveatInfo struct {
	// Condition holds the third party condition to be discharged.
	// This is the only field that most third party dischargers will
	// need to consider.
	Condition []byte

	// FirstPartyPublicKey holds the public key of the party
	// that created the third party caveat.
	FirstPartyPublicKey PublicKey

	// ThirdPartyKeyPair holds the key pair used to decrypt
	// the caveat - the key pair of the discharging service.
	ThirdPartyKeyPair KeyPair

	// RootKey holds the secret root key encoded by the caveat.
	RootKey []byte

	// CaveatId holds the full encoded caveat id from which all
	// the other fields are derived.
	Caveat []byte

	// Version holds the version that was used to encode
	// the caveat id.
	Version Version

	// Id holds the id of the third party caveat (the id that
	// the discharge macaroon should be given). This
	// will differ from Caveat when the caveat information
	// is encoded separately.
	Id []byte

	// Namespace holds the namespace of the first party
	// that created the macaroon, as encoded by the party
	// that added the third party caveat.
	Namespace *checkers.Namespace

ThirdPartyCaveatInfo holds the information decoded from a third party caveat id.

type ThirdPartyInfo

type ThirdPartyInfo struct {
	// PublicKey holds the public key of the third party.
	PublicKey PublicKey

	// Version holds latest the bakery protocol version supported
	// by the discharger.
	Version Version

ThirdPartyInfo holds information on a given third party discharge service.

type ThirdPartyLocator

type ThirdPartyLocator interface {
	// ThirdPartyInfo returns information on the third
	// party at the given location. It returns ErrNotFound if no match is found.
	// This method must be safe to call concurrently.
	ThirdPartyInfo(ctx context.Context, loc string) (ThirdPartyInfo, error)

ThirdPartyLocator is used to find information on third party discharge services.

type ThirdPartyStore

type ThirdPartyStore struct {
	// contains filtered or unexported fields

ThirdPartyStore implements a simple ThirdPartyLocator. A trailing slash on locations is ignored.

func NewThirdPartyStore

func NewThirdPartyStore() *ThirdPartyStore

NewThirdPartyStore returns a new instance of ThirdPartyStore that stores locations in memory.

func (*ThirdPartyStore) AddInfo

func (s *ThirdPartyStore) AddInfo(loc string, info ThirdPartyInfo)

AddInfo associates the given information with the given location, ignoring any trailing slash. This method is OK to call concurrently with sThirdPartyInfo.

func (*ThirdPartyStore) ThirdPartyInfo

func (s *ThirdPartyStore) ThirdPartyInfo(ctx context.Context, loc string) (ThirdPartyInfo, error)

ThirdPartyInfo implements the ThirdPartyLocator interface.

type VerificationError

type VerificationError struct {
	Reason error

VerificationError is used to signify that an error is because of a verification failure rather than because verification could not be done.

func (*VerificationError) Error

func (e *VerificationError) Error() string

type Version

type Version int

Version represents a version of the bakery protocol.

const (
	// In version 0, discharge-required errors use status 407
	Version0 Version = 0
	// In version 1,  discharge-required errors use status 401.
	Version1 Version = 1
	// In version 2, binary macaroons and caveat ids are supported.
	Version2 Version = 2
	// In version 3, we support operations associated with macaroons
	// and external third party caveats.
	Version3      Version = 3
	LatestVersion         = Version3


Path Synopsis
checkers The checkers package provides some standard first-party caveat checkers and some primitives for combining them.
dbrootkeystore Package dbkeystore provides the underlying basis for a bakery.RootKeyStore that uses a database as a persistent store and provides flexible policies for root key storage lifetime.
example This example demonstrates three components: - A target service, representing a web server that wishes to use macaroons for authorization.
identchecker Package identchecker wraps the functionality in the bakery package to add support for authentication via third party caveats.
internal/macaroonpb Package macaroonpb is an internal package that allows us to hide the internal serialization details of macaroon ids.
mgorootkeystore Package mgorootkeystore provides an implementation of bakery.RootKeyStore that uses MongoDB as a persistent store.
postgresrootkeystore Package postgreskeystore provides an implementation of bakery.RootKeyStore that uses Postgres as a persistent store.