Documentation ¶
Overview ¶
Package security defines types and utilities associated with security.
Concept: https://vanadium.github.io/concepts/security.html Tutorial: (forthcoming)
The primitives and APIs defined in this package enable bi-directional, end-to-end authentication between communicating parties; authorization based on that authentication; and secrecy and integrity of all communication.
Overview ¶
The Vanadium security model is centered around the concepts of principals and blessings.
A principal in the Vanadium framework is a public and private key pair. Every RPC is executed on behalf of a principal.
A blessing is a binding of a human-readable name to a principal, valid under some caveats, given by another principal. A principal can have multiple blessings bound to it. For instance, a television principal may have a blessing from the manufacturer (e.g., popularcorp:products:tv) as well as from the owner (e.g., alice:devices:hometv). Principals are authorized for operations based on the blessings bound to them.
A principal can "bless" another principal by binding an extension of one of its own blessings to the other principal. This enables delegation of authority. For example, a principal with the blessing "johndoe" can delegate to his phone by blessing the phone as "johndoe:phone", which in-turn can delegate to the headset by blessing it as "johndoe:phone:headset".
Caveats can be added to a blessing in order to restrict the contexts in which it can be used. Amongst other things, caveats can restrict the duration of use and the set of peers that can be communicated with using a blessing.
Navigating the interfaces ¶
Godoc renders all interfaces in this package in alphabetical order. However, we recommend the following order in order to introduce yourself to the API:
- Principal
- Blessings
- BlessingStore
- BlessingRoots
- NewCaveat
- ThirdPartyCaveat
- NewPublicKeyCaveat
Examples ¶
A principal can decide to name itself anything it wants:
// (in process A) var p1 Principal alice, _ := p1.BlessSelf("alice")
This "alice" blessing can be presented to to another principal (typically a remote process), but that other principal will not recognize this "self-proclaimed" authority:
// (in process B) var p2 Principal ctx, call := GetContextAndCall() // current context and security state names, rejected := RemoteBlessingNames(ctx, call) fmt.Printf("%v %v", names, rejected) // Will print [] ["alice": "..."]
However, p2 can decide to trust the roots of the "alice" blessing and then it will be able to recognize her delegates as well:
// (in process B) AddToRoots(p2, call.RemoteBlessings()) names, rejected := RemoteBlessingNames(ctx, call) fmt.Printf("%v %v", names, rejected) // Will print ["alice"] []
Furthermore, p2 can seek a blessing from "alice":
// (in process A) call := GetCall() // Call under which p2 is seeking a blessing from alice, call.LocalPrincipal = p1 key2 := call.RemoteBlessings().PublicKey() onlyFor10Minutes := NewExpiryCaveat(time.Now().Add(10*time.Minute)) aliceFriend, _ := p1.Bless(key2, alice, "friend", onlyFor10Minutes) SendBlessingToProcessB(aliceFriend)
p2 can then add this blessing to its store such that this blessing will be presented to "alice" (and her delegates) anytime p2 communicates with it in the future:
// (in process B) p2.BlessingStore().Set(aliceFriend, "alice")
p2 can also choose to present multiple blessings to some servers:
// (in process B) charlieFriend := ReceiveBlessingFromSomeWhere() union, _ := UnionOfBlessings(aliceFriend, charlieFriend) p2.BlessingStore().Set(union, "alice:mom")
Thus, when communicating with a "server" that presents the blessing "alice:mom", p2 will declare that he is both "alice's friend" and "charlie's friend" and the server may authorize actions based on this fact.
p2 may also choose that it wants to present these two blessings when acting as a "server", (i.e., when it does not know who the peer is):
// (in process B) default, _ := UnionOfBlessings(aliceFriend, charlieFriend) p2.BlessingStore().SetDefault(default)
Index ¶
- Constants
- Variables
- func AddToRoots(p Principal, blessings Blessings) error
- func BlessingNames(principal Principal, blessings Blessings) []string
- func DefaultBlessingNames(p Principal) (names []string)
- func JoinPatternName(pattern BlessingPattern, name string) string
- func LocalBlessingNames(ctx *context.T, call Call) []string
- func NewErrAuthorizationFailed(ctx *context.T, remote []string, remoteErr []RejectedBlessing, local []string) error
- func NewErrCaveatNotRegistered(ctx *context.T, id uniqueid.Id) error
- func NewErrCaveatParamAny(ctx *context.T, id uniqueid.Id) error
- func NewErrCaveatParamCoding(ctx *context.T, id uniqueid.Id, typ *vdl.Type, err error) error
- func NewErrCaveatParamTypeMismatch(ctx *context.T, id uniqueid.Id, got *vdl.Type, want *vdl.Type) error
- func NewErrCaveatValidation(ctx *context.T, err error) error
- func NewErrConstCaveatValidation(ctx *context.T) error
- func NewErrEndpointAuthorizationFailed(ctx *context.T, endpoint string, remote []string, rejected []RejectedBlessing) error
- func NewErrExpiryCaveatValidation(ctx *context.T, currentTime time.Time, expiryTime time.Time) error
- func NewErrInvalidSigningBlessingCaveat(ctx *context.T, id uniqueid.Id) error
- func NewErrMethodCaveatValidation(ctx *context.T, invokedMethod string, permittedMethods []string) error
- func NewErrPeerBlessingsCaveatValidation(ctx *context.T, peerBlessings []string, permittedPatterns []BlessingPattern) error
- func NewErrPublicKeyNotAllowed(ctx *context.T, got string, want string) error
- func NewErrUnrecognizedRoot(ctx *context.T, rootKey string, details error) error
- func RegisterCaveatValidator(c CaveatDescriptor, validator interface{})
- func VDLReadWireDischarge(dec vdl.Decoder, x *WireDischarge) error
- func WireBlessingsFromNative(wire *WireBlessings, native Blessings) error
- func WireBlessingsToNative(wire WireBlessings, native *Blessings) error
- func WireDischargeFromNative(wire *WireDischarge, native Discharge) error
- func WireDischargeToNative(wire WireDischarge, native *Discharge) error
- type Authorizer
- type BlessingPattern
- func (p BlessingPattern) IsValid() bool
- func (p BlessingPattern) MakeNonExtendable() BlessingPattern
- func (p BlessingPattern) MatchedBy(blessings ...string) bool
- func (p BlessingPattern) PrefixPatterns() []BlessingPattern
- func (x BlessingPattern) VDLIsZero() bool
- func (x *BlessingPattern) VDLRead(dec vdl.Decoder) error
- func (x BlessingPattern) VDLWrite(enc vdl.Encoder) error
- type BlessingRoots
- type BlessingStore
- type Blessings
- func (b Blessings) CouldHaveNames(names []string) bool
- func (b Blessings) Equivalent(blessings Blessings) bool
- func (b Blessings) Expiry() time.Time
- func (b Blessings) IsZero() bool
- func (b Blessings) PublicKey() PublicKey
- func (b Blessings) String() string
- func (b Blessings) ThirdPartyCaveats() []Caveat
- func (b Blessings) UniqueID() []byte
- type Call
- type CallParams
- type Caveat
- func NewCaveat(c CaveatDescriptor, param interface{}) (Caveat, error)
- func NewExpiryCaveat(t time.Time) (Caveat, error)
- func NewMethodCaveat(method string, additionalMethods ...string) (Caveat, error)
- func NewPublicKeyCaveat(discharger PublicKey, location string, requirements ThirdPartyRequirements, ...) (Caveat, error)
- func UnconstrainedUse() Caveat
- type CaveatDescriptor
- type Certificate
- type Discharge
- type DischargeImpetus
- type Hash
- type Principal
- type PublicKey
- type PublicKeyDischarge
- type RejectedBlessing
- type Signature
- type Signer
- type ThirdPartyCaveat
- type ThirdPartyRequirements
- type WireBlessings
- type WireDischarge
- type WireDischargePublicKey
Constants ¶
const AllPrincipals = BlessingPattern("...") // Glob pattern that matches all blessings.
TODO(ataly, ashankar): The semantics of AllPrincipals breaks monotonicity in AccessLists with NotIn clauses. For instance, the AccessList "In: {AllPrincipals}, NotIn: {"foo"} matches the principal that presents no recognizable blessings ([]) however does not match the principal that presents "foo" as the only recognizable blessings (["foo"]) We need to sort this out.
const ChainSeparator = ":" // ChainSeparator joins blessing names to form a blessing chain name.
const NoExtension = BlessingPattern("$")
NoExtension is an optional terminator for a blessing pattern indicating that the pattern cannot match any extensions of the blessing from that point onwards.
const SHA1Hash = Hash("SHA1") // SHA1 cryptographic hash function defined in RFC3174.
const SHA256Hash = Hash("SHA256") // SHA256 cryptographic hash function defined in FIPS 180-4.
const SHA384Hash = Hash("SHA384") // SHA384 cryptographic hash function defined in FIPS 180-2.
const SHA512Hash = Hash("SHA512") // SHA512 cryptographic hash function defined in FIPS 180-2.
const SignatureForBlessingCertificates = "B1" // Signature.Purpose used by a Principal when signing Certificates for creating blessings.
const SignatureForDischarge = "D1" // Signature.Purpose used by a Principal when signing discharges for public-key based third-party caveats.
const SignatureForMessageSigning = "S1" // Signature.Purpose used by a Principal to sign arbitrary messages.
Variables ¶
var ( ErrCaveatNotRegistered = verror.Register("v.io/v23/security.CaveatNotRegistered", verror.NoRetry, "{1:}{2:} no validation function registered for caveat id {3}") ErrCaveatParamAny = verror.Register("v.io/v23/security.CaveatParamAny", verror.NoRetry, "{1:}{2:} caveat {3} uses illegal param type any") ErrCaveatParamTypeMismatch = verror.Register("v.io/v23/security.CaveatParamTypeMismatch", verror.NoRetry, "{1:}{2:} bad param type: caveat {3} got {4}, want {5}") ErrCaveatParamCoding = verror.Register("v.io/v23/security.CaveatParamCoding", verror.NoRetry, "{1:}{2:} unable to encode/decode caveat param(type={4}) for caveat {3}: {5}") ErrCaveatValidation = verror.Register("v.io/v23/security.CaveatValidation", verror.NoRetry, "{1:}{2:} caveat validation failed: {3}") ErrConstCaveatValidation = verror.Register("v.io/v23/security.ConstCaveatValidation", verror.NoRetry, "{1:}{2:} false const caveat always fails validation") ErrExpiryCaveatValidation = verror.Register("v.io/v23/security.ExpiryCaveatValidation", verror.NoRetry, "{1:}{2:} now({3}) is after expiry({4})") ErrMethodCaveatValidation = verror.Register("v.io/v23/security.MethodCaveatValidation", verror.NoRetry, "{1:}{2:} method {3} not in list {4}") ErrPeerBlessingsCaveatValidation = verror.Register("v.io/v23/security.PeerBlessingsCaveatValidation", verror.NoRetry, "{1:}{2:} patterns in peer blessings caveat {4} not matched by the peer {3}") ErrUnrecognizedRoot = verror.Register("v.io/v23/security.UnrecognizedRoot", verror.NoRetry, "{1:}{2:} unrecognized public key {3} in root certificate{:4}") ErrAuthorizationFailed = verror.Register("v.io/v23/security.AuthorizationFailed", verror.NoRetry, "{1:}{2:} principal with blessings {3} (rejected {4}) is not authorized by principal with blessings {5}") ErrInvalidSigningBlessingCaveat = verror.Register("v.io/v23/security.InvalidSigningBlessingCaveat", verror.NoRetry, "{1:}{2:} blessing has caveat with UUID {3} which makes it unsuitable for signing -- please use blessings with just Expiry caveats") ErrPublicKeyNotAllowed = verror.Register("v.io/v23/security.PublicKeyNotAllowed", verror.NoRetry, "{1:}{2:} peer has public key {3}, not the authorized public key {4}") ErrEndpointAuthorizationFailed = verror.Register("v.io/v23/security.EndpointAuthorizationFailed", verror.NoRetry, "{1:}{2:} blessings in endpoint {3} not matched by blessings presented: {4} (rejected {5})") )
var ConstCaveat = CaveatDescriptor{ ParamType: vdl.BoolType, }
ConstCaveat represents a caveat that either always validates or never validates.
var ExpiryCaveat = CaveatDescriptor{ Id: uniqueid.Id{ 166, 76, 45, 1, 25, 251, 163, 52, 128, 113, 254, 235, 47, 48, 128, 0, }, ParamType: __VDLType_struct_22, }
ExpiryCaveat represents a caveat that validates iff the current time is no later the specified time.Time.
var MethodCaveat = CaveatDescriptor{ Id: uniqueid.Id{ 84, 166, 118, 57, 129, 55, 24, 126, 205, 178, 109, 45, 105, 186, 0, 3, }, ParamType: __VDLType_list_23, }
MethodCaveat represents a caveat that validates iff the method being invoked is included in this list. An empty list implies that the caveat is invalid.
var PeerBlessingsCaveat = CaveatDescriptor{ Id: uniqueid.Id{ 5, 119, 248, 86, 76, 142, 95, 254, 255, 142, 43, 31, 77, 109, 128, 0, }, ParamType: __VDLType_list_13, }
PeerBlessingsCaveat represents a caveat that validates iff the peer being communicated with (local end of the call) has a blessing name matching at least one of the patterns in the list. An empty list implies that the caveat is invalid.
var PublicKeyThirdPartyCaveat = CaveatDescriptor{ Id: uniqueid.Id{ 121, 114, 206, 23, 74, 123, 169, 63, 121, 84, 125, 118, 156, 145, 128, 0, }, ParamType: __VDLType_struct_6, }
Functions ¶
func AddToRoots ¶
AddToRoots marks the root principals of all blessing chains represented by 'blessings' as an authority on blessing chains beginning at that root name in p.BlessingRoots().
For example, if blessings represents the blessing chains ["alice:friend:spouse", "charlie:family:daughter"] then AddToRoots(blessing) will mark the root public key of the chain "alice:friend:bob" as the authority on all blessings that match the pattern "alice", and root public key of the chain "charlie:family:daughter" as an authority on all blessings that match the pattern "charlie".
This is a convenience function over extracting the names and public keys of the roots of blessings and invoking p.Roots().Add(...).
func BlessingNames ¶
BlessingNames returns the set of human-readable blessing names encapsulated in blessings.
The returned names are guaranteed to be rooted in principal.Roots, though caveats may not be validated.
The blessings must be bound to principal. There is intentionally no API to obtain blessing names bound to other principals by ignoring caveats. This is to prevent accidental authorization based on potentially invalid names (since caveats are not validated).
func DefaultBlessingNames ¶
DefaultBlessingNames returns the blessing names of the Default Blessings of the provided Principal.
func JoinPatternName ¶
func JoinPatternName(pattern BlessingPattern, name string) string
JoinPatternName embeds the specified pattern into a name.
func LocalBlessingNames ¶
LocalBlessingNames returns the set of human-readable blessing names encapsulated in the blessings object presented by the local end of the call.
This is just a convenience function over:
BlessingNames(call.LocalPrincipal(), call.LocalBlessings())
func NewErrAuthorizationFailed ¶
func NewErrAuthorizationFailed(ctx *context.T, remote []string, remoteErr []RejectedBlessing, local []string) error
NewErrAuthorizationFailed returns an error with the ErrAuthorizationFailed ID.
func NewErrCaveatNotRegistered ¶
NewErrCaveatNotRegistered returns an error with the ErrCaveatNotRegistered ID.
func NewErrCaveatParamAny ¶
NewErrCaveatParamAny returns an error with the ErrCaveatParamAny ID.
func NewErrCaveatParamCoding ¶
NewErrCaveatParamCoding returns an error with the ErrCaveatParamCoding ID.
func NewErrCaveatParamTypeMismatch ¶
func NewErrCaveatParamTypeMismatch(ctx *context.T, id uniqueid.Id, got *vdl.Type, want *vdl.Type) error
NewErrCaveatParamTypeMismatch returns an error with the ErrCaveatParamTypeMismatch ID.
func NewErrCaveatValidation ¶
NewErrCaveatValidation returns an error with the ErrCaveatValidation ID.
func NewErrConstCaveatValidation ¶
NewErrConstCaveatValidation returns an error with the ErrConstCaveatValidation ID.
func NewErrEndpointAuthorizationFailed ¶
func NewErrEndpointAuthorizationFailed(ctx *context.T, endpoint string, remote []string, rejected []RejectedBlessing) error
NewErrEndpointAuthorizationFailed returns an error with the ErrEndpointAuthorizationFailed ID.
func NewErrExpiryCaveatValidation ¶
func NewErrExpiryCaveatValidation(ctx *context.T, currentTime time.Time, expiryTime time.Time) error
NewErrExpiryCaveatValidation returns an error with the ErrExpiryCaveatValidation ID.
func NewErrInvalidSigningBlessingCaveat ¶
NewErrInvalidSigningBlessingCaveat returns an error with the ErrInvalidSigningBlessingCaveat ID.
func NewErrMethodCaveatValidation ¶
func NewErrMethodCaveatValidation(ctx *context.T, invokedMethod string, permittedMethods []string) error
NewErrMethodCaveatValidation returns an error with the ErrMethodCaveatValidation ID.
func NewErrPeerBlessingsCaveatValidation ¶
func NewErrPeerBlessingsCaveatValidation(ctx *context.T, peerBlessings []string, permittedPatterns []BlessingPattern) error
NewErrPeerBlessingsCaveatValidation returns an error with the ErrPeerBlessingsCaveatValidation ID.
func NewErrPublicKeyNotAllowed ¶
NewErrPublicKeyNotAllowed returns an error with the ErrPublicKeyNotAllowed ID.
func NewErrUnrecognizedRoot ¶
NewErrUnrecognizedRoot returns an error with the ErrUnrecognizedRoot ID.
func RegisterCaveatValidator ¶
func RegisterCaveatValidator(c CaveatDescriptor, validator interface{})
RegisterCaveatValidator associates a CaveatDescriptor with the implementation of the validation function.
The validation function must act as if the caveat was obtained from the remote end of the call. In particular, if the caveat is a third-party caveat then 'call.RemoteDischarges()' must be used to validate it.
This function must be called at most once per c.ID, and will panic on duplicate registrations.
func VDLReadWireDischarge ¶
func VDLReadWireDischarge(dec vdl.Decoder, x *WireDischarge) error
func WireBlessingsFromNative ¶
func WireBlessingsFromNative(wire *WireBlessings, native Blessings) error
func WireBlessingsToNative ¶
func WireBlessingsToNative(wire WireBlessings, native *Blessings) error
func WireDischargeFromNative ¶
func WireDischargeFromNative(wire *WireDischarge, native Discharge) error
func WireDischargeToNative ¶
func WireDischargeToNative(wire WireDischarge, native *Discharge) error
Types ¶
type Authorizer ¶
Authorizer is the interface for performing authorization checks.
func AllowEveryone ¶
func AllowEveryone() Authorizer
AllowEveryone returns an Authorizer which implements a policy of always allowing access - irrespective of any parameters of the call or the blessings of the caller.
func DefaultAuthorizer ¶
func DefaultAuthorizer() Authorizer
DefaultAuthorizer returns an Authorizer that implements a "reasonably secure" authorization policy that can be used whenever in doubt.
It has the conservative policy that requires one end of the RPC to have a blessing that is extended from the blessing presented by the other end.
func EndpointAuthorizer ¶
func EndpointAuthorizer() Authorizer
EndpointAuthorizer authorizes principals iff they present blessings that match those specified in call.RemoteEndpoint().
func PublicKeyAuthorizer ¶
func PublicKeyAuthorizer(key PublicKey) Authorizer
PublicKeyAuthorizer only authorizes principals with a specific public key.
Normally, authorizations in Vanadium should be based on blessing names and not public keys, since the former are resilient to key rotations and process replication. However, in rare circumstances it may be possible that blessing names cannot be used (for example, if the local end does not recognize the remote end's blessing root), and the PublicKey might be usable instead.
type BlessingPattern ¶
type BlessingPattern string
BlessingPattern is a pattern that is matched by specific blessings.
A pattern can either be a blessing (slash-separated human-readable string) or a blessing ending in "/$". A pattern ending in "/$" is matched exactly by the blessing specified by the pattern string with the "/$" suffix stripped out. For example, the pattern "a/b/c/$" is matched by exactly by the blessing "a/b/c".
A pattern not ending in "/$" is more permissive, and is also matched by blessings that are extensions of the pattern (including the pattern itself). For example, the pattern "a/b/c" is matched by the blessings "a/b/c", "a/b/c/x", "a/b/c/x/y", etc.
TODO(ataly, ashankar): Define a formal BNF grammar for blessings and blessing patterns.
func DefaultBlessingPatterns ¶
func DefaultBlessingPatterns(p Principal) (patterns []BlessingPattern)
DefaultBlessingPatterns returns the BlessingPatterns of the Default Blessings of the provided Principal.
func SplitPatternName ¶
func SplitPatternName(origName string) (BlessingPattern, string)
SplitPatternName takes an object name and parses out the server blessing pattern. It returns the pattern specified, and the name with the pattern removed.
func (BlessingPattern) IsValid ¶
func (p BlessingPattern) IsValid() bool
IsValid returns true iff the BlessingPattern is well formed, as per the rules described in documentation for the BlessingPattern type.
func (BlessingPattern) MakeNonExtendable ¶
func (p BlessingPattern) MakeNonExtendable() BlessingPattern
MakeNonExtendable returns a pattern that is matched exactly by the blessing specified by the given pattern string.
For example:
onlyAlice := BlessingPattern("google:alice").MakeNonExtendable() onlyAlice.MatchedBy("google:alice") // Returns true onlyAlice.MatchedBy("google") // Returns false onlyAlice.MatchedBy("google:alice:bob") // Returns false
func (BlessingPattern) MatchedBy ¶
func (p BlessingPattern) MatchedBy(blessings ...string) bool
MatchedBy returns true iff one of the presented blessings matches p as per the rules described in documentation for the BlessingPattern type.
func (BlessingPattern) PrefixPatterns ¶
func (p BlessingPattern) PrefixPatterns() []BlessingPattern
PrefixPatterns returns a set of BlessingPatterns that are matched by blessings that either directly match the provided pattern or can be extended to match the provided pattern.
For example: BlessingPattern("google:alice:friend").PrefixPatterns() returns
["google:$", "google:alice:$", "google:alice:friend"]
BlessingPattern("google:alice:friend:$").PrefixPatterns() returns
["google:$", "google:alice:$", "google:alice:friend:$"]
The returned set of BlessingPatterns are ordered by the number of ":"-separated components in the pattern.
func (BlessingPattern) VDLIsZero ¶
func (x BlessingPattern) VDLIsZero() bool
type BlessingRoots ¶
type BlessingRoots interface { // Add marks 'root' (a DER-encoded public key) as an authoritative key // for blessings that match 'pattern'. // // Multiple keys can be added for the same pattern, in which // case all those keys are considered authoritative for // blessings that match the pattern. Add(root []byte, pattern BlessingPattern) error // Recognized returns nil iff the provided (DER-encoded) root public // key as an authority on a pattern that is matched by blessing. Recognized(root []byte, blessing string) error // Dump returns the set of recognized roots as a map from // blessing patterns to the set of authoritative keys for that // pattern. Dump() map[BlessingPattern][]PublicKey // DebugString returns a human-readable string description of the roots. // This description is detailed and lists out all the roots. Use // fmt.Sprintf("%v", ...) for a more succinct description. DebugString() string }
BlessingRoots hosts the set of authoritative public keys for roots of blessings.
See also: https://vanadium.github.io/glossary.html#blessing-root
type BlessingStore ¶
type BlessingStore interface { // Set marks the set of blessings to be shared with peers. // // Set(b, pattern) marks the intention to reveal b to peers // who present blessings of their own matching pattern. // // If multiple calls to Set are made with the same pattern, the // last call prevails. // // Set(Blessings{}, pattern) can be used to remove the blessings // previously associated with the pattern (by a prior call to Set). // // It is an error to call Set with "blessings" whose public key does // not match the PublicKey of the principal for which this store hosts // blessings. // // Set returns the Blessings object which was previously associated // with the pattern. Set(blessings Blessings, forPeers BlessingPattern) (Blessings, error) // ForPeer returns the set of blessings that have been previously // added to the store with an intent of being shared with peers // that have at least one of the provided blessings. // // If no peerBlessings are provided then blessings marked for all peers // (i.e., added with the AllPrincipals pattern) is returned. // // Returns the zero value if there are no matching blessings in the store. ForPeer(peerBlessings ...string) Blessings // SetDefault sets up the Blessings made available on a subsequent call // to Default. // // It is an error to call SetDefault with a blessings whose public key // does not match the PublicKey of the principal for which this store // hosts blessings. SetDefault(blessings Blessings) error // Default returns the blessings to be shared with peers for which no // other information is available in order to select blessings from the // store. // // For example, Default can be used by servers to identify themselves // to clients before the client has identified itself. // // Default returns the blessings provided to the last call to // SetDefault and a channel which will be closed when the // Default changes (i.e., SetDefault is called again). // // Returns the zero value if there is no usable blessings. Default() (Blessings, <-chan struct{}) // PublicKey returns the public key of the Principal for which // this store hosts blessings. PublicKey() PublicKey // PeerBlessings returns all the blessings that the BlessingStore // currently holds for various peers. PeerBlessings() map[BlessingPattern]Blessings // CacheDischarge inserts the discharge for the provided impetus and caveat into the cache. CacheDischarge(discharge Discharge, caveat Caveat, impetus DischargeImpetus) // ClearDischarges clears the input discharges from the BlessingStore's // discharge cache. ClearDischarges(discharges ...Discharge) // Discharge takes a caveat and DischargeImpetus and returns a cached discharge // and the time at which it was cached. Zero values are returned if no // corresponding cached discharge can be found. Note that in certain upgrade // situations a zero cacheTime may be returned if the real cache time cannot // be determined. Discharge(caveat Caveat, impetus DischargeImpetus) (discharge Discharge, cacheTime time.Time) // DebugString return a human-readable string description of the store. // This description is detailed and lists out the contents of the store. // Use fmt.Sprintf("%v", ...) for a more succinct description. DebugString() string }
BlessingStore is the interface for storing blessings bound to a principal and managing the subset of blessings to be presented to particular peers. BlessingStore implementations may also cache Discharges for third-party caveats on blessings, allowing unexpired Discharges to be reused.
type Blessings ¶
type Blessings struct {
// contains filtered or unexported fields
}
Blessings encapsulates all cryptographic operations required to prove that a set of (human-readable) blessing names are bound to a principal in a specific call.
Blessings objects are meant to be presented to other principals to authenticate and authorize actions. The functions 'LocalBlessingNames', 'SigningBlessingNames' and 'RemoteBlessingNames' defined in this package can be used to uncover the blessing names encapsulated in these objects.
Blessings objects are immutable and multiple goroutines may invoke methods on them simultaneously.
See also: https://vanadium.github.io/glossary.html#blessing
func NamelessBlessing ¶
NamelessBlessing returns a blessings object that has no names, only the provided public key.
func RootBlessings ¶
RootBlessings returns the blessings of the roots of b. In other words, RootBlessings returns the blessings of the identity providers encapsulated in b.
In particular:
AddToRoots(p, b)
is equivalent to:
for _, root := range RootBlessings(b) { AddToRoots(p, root) }
Why would you use the latter? Only to share roots with another process, without revealing your complete blessings and using fewer bytes.
func SigningBlessings ¶
SigningBlessings returns a blessings object that encapsulates the subset of names of the provided blessings object that can be used to sign data at rest.
The names of the returned blessings object can be obtained using the 'SigningNames' function.
func UnionOfBlessings ¶
UnionOfBlessings returns a Blessings object that carries the union of the provided blessings.
All provided Blessings must have the same PublicKey.
UnionOfBlessings with no arguments returns (nil, nil).
func (Blessings) CouldHaveNames ¶
CouldHaveNames returns true iff the blessings 'b' encapsulates the provided set of blessing names.
This check ignores all caveats on the blessing name and the recognition status of its blessing root.
func (Blessings) Equivalent ¶
Equivalent returns true if 'b' and 'blessings' can be used interchangeably, i.e., 'b' will be authorized wherever 'blessings' is and vice-versa.
func (Blessings) Expiry ¶
Expiry returns the time at which b will no longer be valid, or the zero value of time.Time if the blessing does not expire.
func (Blessings) IsZero ¶
IsZero returns true if b represents the zero value of blessings (an empty set).
func (Blessings) PublicKey ¶
PublicKey returns the public key of the principal to which blessings obtained from this object are bound.
Can return nil if b is the zero value.
func (Blessings) ThirdPartyCaveats ¶
ThirdPartyCaveats returns the set of third-party restrictions on the scope of the blessings (i.e., the subset of Caveats for which ThirdPartyDetails will be non-nil).
func (Blessings) UniqueID ¶
UniqueID returns an identifier of the set of blessings. Two blessings objects with the same UniqueID are interchangeable for any authorization decisions.
The converse is not guaranteed at this time. Two interchangeable blessings objects may in theory have different UniqueIDs.
type Call ¶
type Call interface { // Timestamp returns the time at which the authorization state is to be checked. Timestamp() time.Time // Method returns the method being invoked. Method() string // MethodTags returns the tags attached to the method, typically through the // interface specification in VDL. MethodTags() []*vdl.Value // Suffix returns the object name suffix for the request. Suffix() string // LocalDischarges specify discharges for third-party caveats presented by // the local end of the call. It maps a third-party caveat identifier to the // corresponding discharge. LocalDischarges() map[string]Discharge // RemoteDischarges specify discharges for third-party caveats presented by // the remote end of the call. It maps a third-party caveat identifier to the // corresponding discharge. RemoteDischarges() map[string]Discharge // LocalPrincipal returns the principal used to authenticate to the remote end. LocalPrincipal() Principal // LocalBlessings returns the blessings (bound to the local end) // provided to the remote end for authentication. LocalBlessings() Blessings // RemoteBlessings returns the blessings (bound to the remote end) // provided to the local end during authentication. RemoteBlessings() Blessings // LocalEndpoint() returns the Endpoint of the principal at the local // end of communication. LocalEndpoint() naming.Endpoint // RemoteEndpoint() returns the Endpoint of the principal at the remote end // of communication. RemoteEndpoint() naming.Endpoint }
Call defines the state available for authorizing a principal.
type CallParams ¶
type CallParams struct { Timestamp time.Time // Time at which the authorization is to be checked. Method string // Method being invoked. MethodTags []*vdl.Value // Method tags, typically specified in VDL. Suffix string // Object suffix on which the method is being invoked. LocalPrincipal Principal // Principal at the local end of a request. LocalBlessings Blessings // Blessings presented to the remote end. LocalEndpoint naming.Endpoint // Endpoint of local end of communication. RemoteBlessings Blessings // Blessings presented by the remote end. RemoteDischarges map[string]Discharge // Map of third-party caveat identifiers to corresponding discharges shared by the remote end. LocalDischarges map[string]Discharge // Map of third-party caveat identifiers to corresponding discharges shared by the local end. RemoteEndpoint naming.Endpoint // Endpoint of the remote end of communication (as seen by the local end) }
CallParams is used to create Call objects using the NewCall function.
func (*CallParams) Copy ¶
func (p *CallParams) Copy(c Call)
Copy fills in p with a copy of the values in c.
type Caveat ¶
type Caveat struct { Id uniqueid.Id // The identifier of the caveat validation function. ParamVom []byte // VOM-encoded bytes of the parameters to be provided to the validation function. }
Caveat is a condition on the validity of a blessing/discharge.
These conditions are provided when asking a principal to create a blessing/discharge and are verified when extracting blessings (Blessings.ForName in the Go API).
Given a Hash, the message digest of a caveat is: Hash(Hash(Id), Hash(ParamVom))
func NewCaveat ¶
func NewCaveat(c CaveatDescriptor, param interface{}) (Caveat, error)
NewCaveat returns a Caveat that requires validation by the validation function correponding to c and uses the provided parameters.
func NewExpiryCaveat ¶
NewExpiryCaveat returns a Caveat that validates iff the current time is before t.
func NewMethodCaveat ¶
NewMethodCaveat returns a Caveat that validates iff the method being invoked by the peer is listed in an argument to this function.
func NewPublicKeyCaveat ¶
func NewPublicKeyCaveat(discharger PublicKey, location string, requirements ThirdPartyRequirements, caveat Caveat, additionalCaveats ...Caveat) (Caveat, error)
NewPublicKeyCaveat returns a third-party caveat, i.e., the returned Caveat will be valid only when a discharge signed by discharger is issued.
Location specifies the expected address at which the third-party service is found (and which issues discharges).
The discharger will validate all provided caveats (caveat, additionalCaveats) before issuing a discharge.
func UnconstrainedUse ¶
func UnconstrainedUse() Caveat
UnconstrainedUse returns a Caveat implementation that never fails to validate. This is useful only for providing unconstrained blessings/discharges to another principal.
func (*Caveat) ThirdPartyDetails ¶
func (c *Caveat) ThirdPartyDetails() ThirdPartyCaveat
ThirdPartyDetails returns nil if c is not a third party caveat, or details about the third party otherwise.
func (*Caveat) Validate ¶
Validate tests if 'c' is satisfied under 'call', returning nil if it is or an error otherwise.
It assumes that 'c' was found on a credential obtained from the remote end of the call. In particular, if 'c' is a third-party caveat then it uses the call.RemoteDischarges() to validate it.
type CaveatDescriptor ¶
type CaveatDescriptor struct { Id uniqueid.Id // The identifier of the caveat validation function. ParamType *vdl.Type // The type of the parameter expected by the validation function. }
CaveatDescriptor defines an association between a caveat validation function (addressed by globally unique identifier) and the data needed by the validation function.
For a validator to be invoked, a validation function must be registered with the validator description in the language that the function is defined in.
func (CaveatDescriptor) VDLIsZero ¶
func (x CaveatDescriptor) VDLIsZero() bool
type Certificate ¶
type Certificate struct { Extension string // Human-readable string extension bound to PublicKey. PublicKey []byte // DER-encoded PKIX public key. Caveats []Caveat // Caveats on the binding of Name to PublicKey. Signature Signature // Signature by the blessing principal that binds the extension to the public key. }
Certificate represents the cryptographic proof of the binding of extensions of a blessing held by one principal to another (represented by a public key) under specific caveats.
For example, if a principal P1 has a blessing "alice", then it can extend it with a Certificate to generate the blessing "alice/friend" for another principal P2.
func (Certificate) VDLIsZero ¶
func (x Certificate) VDLIsZero() bool
type Discharge ¶
type Discharge struct {
// contains filtered or unexported fields
}
Discharge represents a "proof" required for satisfying a ThirdPartyCaveat.
A discharge may have caveats of its own (including ThirdPartyCaveats) that restrict the context in which the discharge is usable.
Discharge objects are immutable and multiple goroutines may invoke methods on a Discharge simultaneously.
See also: https://vanadium.github.io/glossary.html#discharge
func (Discharge) Equivalent ¶
Equivalent returns true if 'd' and 'discharge' can be used interchangeably, i.e. any authorizations that are enabled by 'd' will be enabled by 'discharge' and vice versa.
func (Discharge) Expiry ¶
Expiry returns the time at which d will no longer be valid, or the zero value of time.Time if the discharge does not expire.
func (Discharge) ID ¶
ID returns the identifier for the third-party caveat that d is a discharge for.
func (Discharge) ThirdPartyCaveats ¶
func (d Discharge) ThirdPartyCaveats() []ThirdPartyCaveat
ThirdPartyCaveats returns the set of third-party caveats on the scope of the discharge.
type DischargeImpetus ¶
type DischargeImpetus struct { Server []BlessingPattern // The client intends to use the discharge to communicate with a server that has a blessing matching one of the patterns in this set. Method string // Name of the method being invoked by the client. Arguments []*vom.RawBytes // Arguments to the method invocation. }
DischargeImpetus encapsulates the motivation for a discharge being sought.
These values are reported by a principal that is requesting a Discharge for a third-party caveat on one of its blessings. The third-party issues discharges cannot safely assume that all these values are provided, or that they are provided honestly.
Implementations of services that issue discharges are encouraged to add caveats to the discharge that bind the discharge to the impetus, thereby rendering the discharge unsuable for any other purpose.
func (DischargeImpetus) VDLIsZero ¶
func (x DischargeImpetus) VDLIsZero() bool
type Hash ¶
type Hash string
Hash identifies a cryptographic hash function approved for use in signature algorithms.
type Principal ¶
type Principal interface { // Bless binds extensions of blessings held by this principal to // another principal (represented by its public key). // // For example, a principal with the blessings "google:alice" // and "v23:alice" can bind the blessings "google:alice:friend" // and "v23:alice:friend" to another principal using: // Bless(<other principal>, <google:alice, v23:alice>, "friend", ...) // // To discourage unconstrained delegation of authority, the interface // requires at least one caveat to be provided. If unconstrained delegation // is desired, the UnconstrainedUse function can be used to produce // this argument. // // with.PublicKey must be the same as the principal's public key. Bless(key PublicKey, with Blessings, extension string, caveat Caveat, additionalCaveats ...Caveat) (Blessings, error) // BlessSelf creates a blessing with the provided name for this principal. BlessSelf(name string, caveats ...Caveat) (Blessings, error) // Sign uses the private key of the principal to sign message. Sign(message []byte) (Signature, error) // MintDischarge generates a discharge for 'tp'. // // It assumes that it is okay to generate a discharge, i.e., any // restrictions encoded within 'tp' are satisfied. // // The returned discharge will be usable only if the provided caveats // are met when using the discharge. MintDischarge(forThirdPartyCaveat, caveatOnDischarge Caveat, additionalCaveatsOnDischarge ...Caveat) (Discharge, error) // PublicKey returns the public key counterpart of the private key held // by the Principal. PublicKey() PublicKey // BlessingStore provides access to the BlessingStore containing blessings // that have been granted to this principal. BlessingStore() BlessingStore // Roots returns the set of recognized authorities (identified by their // public keys) on blessings that match specific patterns Roots() BlessingRoots }
Principal represents an entity capable of making or receiving RPCs. Principals have a unique (public, private) key pair, have (zero or more) blessings bound to them and can bless other principals.
Multiple goroutines may invoke methods on a Principal simultaneously.
See also: https://vanadium.github.io/glossary.html#principal
func CreatePrincipal ¶
func CreatePrincipal(signer Signer, store BlessingStore, roots BlessingRoots) (Principal, error)
CreatePrincipal returns a Principal that uses 'signer' for all private key operations, 'store' for storing blessings bound to the Principal and 'roots' for the set of authoritative public keys on blessings recognized by this Principal.
If provided 'roots' is nil then the Principal does not trust any public keys and all subsequent 'AddToRoots' operations fail.
It returns an error if store.PublicKey does not match signer.PublicKey.
NOTE: v.io/x/ref/lib/testutil/security provides utility methods for creating principals for testing purposes.
type PublicKey ¶
type PublicKey interface { encoding.BinaryMarshaler fmt.Stringer // contains filtered or unexported methods }
PublicKey represents a public key using an unspecified algorithm.
MarshalBinary returns the DER-encoded PKIX representation of the public key, while UnmarshalPublicKey creates a PublicKey object from the marshaled bytes.
String returns a human-readable representation of the public key.
func NewECDSAPublicKey ¶
NewECDSAPublicKey creates a PublicKey object that uses the ECDSA algorithm and the provided ECDSA public key.
func UnmarshalPublicKey ¶
UnmarshalPublicKey returns a PublicKey object from the DER-encoded PKIX represntation of it (typically obtianed via PublicKey.MarshalBinary).
type PublicKeyDischarge ¶
type PublicKeyDischarge struct { ThirdPartyCaveatId string // Id of the third party caveat for which this discharge was issued. Caveats []Caveat // Caveats on the use of this discharge. Signature Signature // Signature of the content hash of this discharge by the discharger. }
PublicKeyDischarge represents a discharge for third party caveats that require a signature from a third-party's public key.
The message digest of this structure is computed as follows: hash(hash(ThirdPartyCaveatId), hash(Caveats[0]), hash(Caveats[1]), ...), where hash is a cryptographic hash function with a security strength equivalent to the strength of the public key of the principal issuing the discharge.
func (*PublicKeyDischarge) String ¶
func (d *PublicKeyDischarge) String() string
func (PublicKeyDischarge) VDLIsZero ¶
func (x PublicKeyDischarge) VDLIsZero() bool
type RejectedBlessing ¶
RejectedBlessing describes why a blessing failed validation.
func RemoteBlessingNames ¶
func RemoteBlessingNames(ctx *context.T, call Call) ([]string, []RejectedBlessing)
RemoteBlessingNames returns the validated set of human-readable blessing names encapsulated in the blessings object presented by the remote end of a call.
The blessing names are guaranteed to:
(1) Satisfy all the caveats associated with them, in the context of the call. (2) Be rooted in call.LocalPrincipal.Roots.
Caveats are considered satisfied for the 'call' if the CaveatValidator implementation can be found in the address space of the caller and Validate returns nil.
RemoteBlessingNames also returns the RejectedBlessings for each blessing name that cannot be validated.
func SigningBlessingNames ¶
func SigningBlessingNames(ctx *context.T, p Principal, blessings Blessings) ([]string, []RejectedBlessing)
SigningBlessingNames returns the validated set of human-readable blessing names encapsulated in the provided signing blessings object, as determined by the provided principal.
This function also returns the RejectedBlessings for each blessing name that cannot be validated. TODO(ataly): While the principal is encapsulated inside context.T, we can't extract it due to an import cycle issue. Therefore at the moment we have the principal separately passed to this function. We should clean this up.
func (RejectedBlessing) String ¶
func (i RejectedBlessing) String() string
func (RejectedBlessing) VDLIsZero ¶
func (x RejectedBlessing) VDLIsZero() bool
type Signature ¶
type Signature struct { // Purpose of the signature. Can be used to prevent type attacks. // (See Section 4.2 of http://www-users.cs.york.ac.uk/~jac/PublishedPapers/reviewV1_1997.pdf for example). // The actual signature (R, S values for ECDSA keys) is produced by signing: Hash(Hash(message), Hash(Purpose)). Purpose []byte // Cryptographic hash function applied to the message before computing the signature. Hash Hash // Pair of integers that make up an ECDSA signature. R []byte S []byte }
Signature represents a digital signature.
type Signer ¶
type Signer interface { // Sign signs an arbitrary length message using the private key associated // with this Signer. // // The provided purpose is used to avoid "type attacks", wherein an honest // entity is cheated into interpreting a field in a message as one with a // type other than the intended one. Sign(purpose, message []byte) (Signature, error) // PublicKey returns the public key corresponding to the Signer's private key. PublicKey() PublicKey }
Signer is the interface for signing arbitrary length messages using private keys.
Multiple goroutines may invoke methods on a Signer simultaneously.
func NewECDSASigner ¶
NewECDSASigner creates a Signer that uses the provided function to sign messages.
func NewInMemoryECDSASigner ¶
func NewInMemoryECDSASigner(key *ecdsa.PrivateKey) Signer
NewInMemoryECDSASigner creates a Signer that uses the provided ECDSA private key to sign messages. This private key is kept in the clear in the memory of the running process.
type ThirdPartyCaveat ¶
type ThirdPartyCaveat interface { // ID returns a cryptographically unique identifier for the ThirdPartCaveat. ID() string // Location returns the Vanadium object name of the discharging third-party. Location() string // Requirements lists the information that the third-party requires // in order to issue a discharge. Requirements() ThirdPartyRequirements // Dischargeable validates all restrictions encoded within the third-party // caveat under the current call and returns nil iff they have been satisfied, // and thus ensures that it is okay to generate a discharge for this // ThirdPartyCaveat. // // It assumes that the ThirdPartCaveat was obtained from the remote end of // call. Dischargeable(ctx *context.T, call Call) error }
ThirdPartyCaveat is a restriction on the applicability of a blessing that is considered satisfied only when accompanied with a specific "discharge" from the third-party specified in the caveat. (The first two parties are the ones presenting a blessing and the one making authorization decisions based on the blessing presented).
Multiple goroutines may invoke methods on a ThirdPartyCaveat simultaneously.
See also: https://vanadium.github.io/glossary.html#third-party-caveat
type ThirdPartyRequirements ¶
type ThirdPartyRequirements struct { ReportServer bool // The blessings presented by the server of an IPC call. ReportMethod bool // The name of the method being invoked. ReportArguments bool // Arguments to the method being invoked. }
ThirdPartyRequirements specifies the information required by the third-party that will issue discharges for third-party caveats.
These requirements are typically used to construct a DischargeImpetus, which will be sent to the third-party.
func (ThirdPartyRequirements) VDLIsZero ¶
func (x ThirdPartyRequirements) VDLIsZero() bool
type WireBlessings ¶
type WireBlessings struct { // CertificateChains is an array of chains of certificates that bind // a blessing to the public key in the last certificate of the chain. CertificateChains [][]Certificate }
WireBlessings encapsulates wire format of a set of blessings and the corresponding cryptographic proof that binds them to a principal (identified by a public key).
This structure is the "wire" format for sending and receiving blessings in RPCs or marshaling to persistent storage. Typically, languages will provide a factory function that converts this wire representation to a more usable object to inspect and manipulate these blessings.
func MarshalBlessings ¶
func MarshalBlessings(b Blessings) WireBlessings
TODO(ashankar): Get rid of this function? It allows users to mess with the integrity of 'b'.
func (WireBlessings) VDLIsZero ¶
func (x WireBlessings) VDLIsZero() bool
type WireDischarge ¶
type WireDischarge interface { // Index returns the field index. Index() int // Interface returns the field value as an interface. Interface() interface{} // Name returns the field name. Name() string VDLIsZero() bool VDLWrite(vdl.Encoder) error // contains filtered or unexported methods }
WireDischarge represents any single field of the WireDischarge union type.
WireDischarge encapsulates the wire format of a third-party caveat Discharge.
type WireDischargePublicKey ¶
type WireDischargePublicKey struct{ Value PublicKeyDischarge } // Discharge for PublicKeyThirdPartyCaveat
WireDischargePublicKey represents field PublicKey of the WireDischarge union type.
func (WireDischargePublicKey) Index ¶
func (x WireDischargePublicKey) Index() int
func (WireDischargePublicKey) Interface ¶
func (x WireDischargePublicKey) Interface() interface{}
func (WireDischargePublicKey) Name ¶
func (x WireDischargePublicKey) Name() string
func (WireDischargePublicKey) VDLIsZero ¶
func (x WireDischargePublicKey) VDLIsZero() bool
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package access defines types and interfaces for dynamic access control.
|
Package access defines types and interfaces for dynamic access control. |
internal
Package internal provides a VDL specification for a service used in the unittest of the access package.
|
Package internal provides a VDL specification for a service used in the unittest of the access package. |