Merge "veyron/runtimes/google/lib/sync/semaphore: update comment about the behavior of Close() w.r.t. Dec/DecN."
diff --git a/lib/glob/glob.go b/lib/glob/glob.go
index b1356c1..a69be73 100644
--- a/lib/glob/glob.go
+++ b/lib/glob/glob.go
@@ -75,42 +75,49 @@
 }
 
 // MatchInitialSegment tries to match segment against the initial element of g.
-// Returns a boolean indicating whether the match was successful and the
-// Glob representing the unmatched remainder of g.
-func (g *Glob) MatchInitialSegment(segment string) (bool, *Glob) {
+// Returns:
+// matched, a boolean indicating whether the match was successful;
+// exact, a boolean indicating whether segment matched a fixed string pattern;
+// remainder, a Glob representing the unmatched remainder of g.
+func (g *Glob) MatchInitialSegment(segment string) (matched bool, exact bool, remainder *Glob) {
 	if len(g.elems) == 0 {
 		if !g.recursive {
-			return false, nil
+			return false, false, nil
 		}
-		return true, g
+		return true, true, g
 	}
 
 	if matches, err := filepath.Match(g.elems[0], segment); err != nil {
 		panic("Error in glob pattern found.")
 	} else if matches {
-		return true, g.Split(1)
+		_, fixed := isFixed(g.elems[0])
+		return true, fixed, g.Split(1)
 	}
-	return false, nil
+	return false, false, nil
 }
 
 // PartialMatch tries matching elems against part of a glob pattern.
-// The first return value is true if each element e_i of elems matches
-// the (start + i)th element of the glob pattern.  If the first return
-// value is true, the second return value returns the unmatched suffix
-// of the pattern.  It will be empty if the pattern is completely
-// matched.
+// Returns:
+// matched, a boolean indicating whether each element e_i of elems matches the
+// (start + i)th element of the glob pattern;
+// exact, a boolean indicating whether elems matched a fixed string pattern;
+// remainder, a Glob representing the unmatched remainder of g. remainder will
+// be empty if the pattern is completely matched.
 //
 // Note that if the glob is recursive elems can have more elements then
 // the glob pattern and still get a true result.
-func (g *Glob) PartialMatch(start int, elems []string) (bool, *Glob) {
+func (g *Glob) PartialMatch(start int, elems []string) (matched bool, exact bool, remainder *Glob) {
 	g = g.Split(start)
-	for ; len(elems) > 0; elems = elems[1:] {
-		var matched bool
-		if matched, g = g.MatchInitialSegment(elems[0]); !matched {
-			return false, nil
+	allExact := true
+	for i := 0; i < len(elems); i++ {
+		var matched, exact bool
+		if matched, exact, g = g.MatchInitialSegment(elems[i]); !matched {
+			return false, false, nil
+		} else if !exact {
+			allExact = false
 		}
 	}
-	return true, g
+	return true, allExact, g
 }
 
 // isFixed returns the unescaped string and true if 's' is a pattern specifying
diff --git a/lib/glob/glob_test.go b/lib/glob/glob_test.go
index bbef347..785a1eb 100644
--- a/lib/glob/glob_test.go
+++ b/lib/glob/glob_test.go
@@ -38,3 +38,63 @@
 		}
 	}
 }
+
+func TestExactMatch(t *testing.T) {
+	tests := []struct {
+		pattern string
+		elems   []string
+		matched bool
+		exact   bool
+	}{
+		// Test one element, fixed.
+		{"a", []string{"a"}, true, true},
+		{"a", []string{"b"}, false, false},
+		{"\\\\", []string{"\\"}, true, true},
+		// Test one element, containing *.
+		{"*", []string{"*"}, true, false},
+		{"*", []string{"abc"}, true, false},
+		{"\\*", []string{"*"}, true, true},
+		{"\\*", []string{"abc"}, false, false},
+		{"\\\\*", []string{"\\"}, true, false},
+		{"\\\\*", []string{"\\*"}, true, false},
+		{"\\\\*", []string{"\\abc"}, true, false},
+		// Test one element, containing ?.
+		{"?", []string{"?"}, true, false},
+		{"?", []string{"a"}, true, false},
+		{"\\?", []string{"?"}, true, true},
+		{"\\?", []string{"a"}, false, false},
+		{"\\\\?", []string{"\\"}, false, false},
+		{"\\\\?", []string{"\\?"}, true, false},
+		{"\\\\?", []string{"\\a"}, true, false},
+		// Test one element, containing [].
+		{"[abc]", []string{"c"}, true, false},
+		{"\\[abc\\]", []string{"[abc]"}, true, true},
+		{"\\[abc\\]", []string{"a"}, false, false},
+		{"\\\\[abc]", []string{"\\a"}, true, false},
+		{"\\\\[abc]", []string{"a"}, false, false},
+		{"[\\\\]", []string{"\\"}, true, false},
+		{"[\\\\]", []string{"a"}, false, false},
+		// Test multiple elements.
+		{"a/b", []string{"a", "b"}, true, true},
+		{"a/\\*", []string{"a", "*"}, true, true},
+		{"a/\\?", []string{"a", "?"}, true, true},
+		{"a/\\[b\\]", []string{"a", "[b]"}, true, true},
+		{"a/*", []string{"a", "bc"}, true, false},
+		{"a/?", []string{"a", "b"}, true, false},
+		{"a/[bc]", []string{"a", "b"}, true, false},
+		{"a/*/c", []string{"a", "b", "c"}, true, false},
+		{"a/?/c", []string{"a", "b", "c"}, true, false},
+		{"a/[bc]/d", []string{"a", "b", "d"}, true, false},
+	}
+	for _, test := range tests {
+		g, err := Parse(test.pattern)
+		if err != nil {
+			t.Fatalf("parsing %q: %q", test.pattern, err.Error())
+		}
+		matched, exact, _ := g.PartialMatch(0, test.elems)
+		if matched != test.matched || exact != test.exact {
+			t.Fatalf("%v.PartialMatch(0, %v) got (%v, %v), expected (%v, %v)",
+				test.pattern, test.elems, matched, exact, test.matched, test.exact)
+		}
+	}
+}
diff --git a/lib/stats/glob.go b/lib/stats/glob.go
index f2db758..1390853 100644
--- a/lib/stats/glob.go
+++ b/lib/stats/glob.go
@@ -50,7 +50,7 @@
 		return
 	}
 	for name, child := range n.children {
-		if ok, left := g.MatchInitialSegment(name); ok {
+		if ok, _, left := g.MatchInitialSegment(name); ok {
 			globStepLocked(path.Join(prefix, name), left, child, updatedSince, includeValues, result)
 		}
 	}
diff --git a/profiles/roaming/init.go b/profiles/roaming/init.go
index d5221f0..ce5862a 100644
--- a/profiles/roaming/init.go
+++ b/profiles/roaming/init.go
@@ -43,11 +43,6 @@
 	flag.StringVar(&listenProxyFlag, "veyron.proxy", "", "proxy to use")
 
 	rt.RegisterProfile(New())
-	ListenSpec = &ipc.ListenSpec{
-		Protocol: listenProtocolFlag.Protocol,
-		Address:  listenAddressFlag.String(),
-		Proxy:    listenProxyFlag,
-	}
 }
 
 type profile struct {
@@ -92,6 +87,12 @@
 func (p *profile) Init(rt veyron2.Runtime, publisher *config.Publisher) {
 	log := rt.Logger()
 
+	ListenSpec = &ipc.ListenSpec{
+		Protocol: listenProtocolFlag.Protocol,
+		Address:  listenAddressFlag.String(),
+		Proxy:    listenProxyFlag,
+	}
+
 	state, err := netstate.GetAccessibleIPs()
 	if err != nil {
 		log.Infof("failed to determine network state")
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index bb9f3b6..be1655c 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -23,7 +23,6 @@
 	isecurity "veyron.io/veyron/veyron/runtimes/google/security"
 	tnaming "veyron.io/veyron/veyron/runtimes/google/testing/mocks/naming"
 	vsecurity "veyron.io/veyron/veyron/security"
-	"veyron.io/veyron/veyron/security/caveat"
 
 	"veyron.io/veyron/veyron2"
 	"veyron.io/veyron/veyron2/ipc"
@@ -569,7 +568,7 @@
 }
 
 func mkThirdPartyCaveat(discharger security.PublicID, location string, c security.Caveat) security.Caveat {
-	tpc, err := caveat.NewPublicKeyCaveat(c, discharger.PublicKey(), location, security.ThirdPartyRequirements{})
+	tpc, err := security.NewPublicKeyCaveat(discharger.PublicKey(), location, security.ThirdPartyRequirements{}, c)
 	if err != nil {
 		panic(err)
 	}
@@ -605,7 +604,7 @@
 		dischargerID = serverID.PublicID()
 
 		mkClientID = func(req security.ThirdPartyRequirements) security.PrivateID {
-			tpc, err := caveat.NewPublicKeyCaveat(newCaveat(alwaysValidCaveat{}), dischargerID.PublicKey(), "mountpoint/discharger", req)
+			tpc, err := security.NewPublicKeyCaveat(dischargerID.PublicKey(), "mountpoint/discharger", req, newCaveat(alwaysValidCaveat{}))
 			if err != nil {
 				t.Fatalf("Failed to create ThirdPartyCaveat: %v", err)
 			}
diff --git a/runtimes/google/naming/namespace/all_test.go b/runtimes/google/naming/namespace/all_test.go
index 479b5bd..bbac581 100644
--- a/runtimes/google/naming/namespace/all_test.go
+++ b/runtimes/google/naming/namespace/all_test.go
@@ -91,7 +91,7 @@
 	if g.Finished() || len(tree) == 0 {
 		return nil
 	}
-	if ok, left := g.MatchInitialSegment(tree[0]); ok {
+	if ok, _, left := g.MatchInitialSegment(tree[0]); ok {
 		if err := t.globLoop(call, naming.Join(prefix, tree[0]), left, tree[1:]); err != nil {
 			return err
 		}
diff --git a/runtimes/google/security/identity_chain.go b/runtimes/google/security/identity_chain.go
index d21aea6..2855a36 100644
--- a/runtimes/google/security/identity_chain.go
+++ b/runtimes/google/security/identity_chain.go
@@ -13,7 +13,6 @@
 
 	"veyron.io/veyron/veyron/runtimes/google/security/keys"
 	vsecurity "veyron.io/veyron/veyron/security"
-	"veyron.io/veyron/veyron/security/caveat"
 
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/security/wire"
@@ -232,7 +231,16 @@
 }
 
 func (id *chainPrivateID) MintDischarge(cav security.ThirdPartyCaveat, ctx security.Context, duration time.Duration, dischargeCaveats []security.Caveat) (security.Discharge, error) {
-	return caveat.NewPublicKeyDischarge(id, cav, ctx, duration, dischargeCaveats)
+	// TODO(ashankar): HACK using new API to fit into old. This will go away anyway when we get rid of PrivateID and PublicID before release.
+	principal, err := security.CreatePrincipal(id.signer)
+	if err != nil {
+		return nil, err
+	}
+	expiry, err := security.ExpiryCaveat(time.Now().Add(duration))
+	if err != nil {
+		return nil, err
+	}
+	return principal.MintDischarge(cav, ctx, expiry, dischargeCaveats...)
 }
 
 func (id *chainPrivateID) Sign(message []byte) (security.Signature, error) {
diff --git a/runtimes/google/security/identity_test.go b/runtimes/google/security/identity_test.go
index 33b9726..c10538f 100644
--- a/runtimes/google/security/identity_test.go
+++ b/runtimes/google/security/identity_test.go
@@ -11,7 +11,6 @@
 	"time"
 
 	"veyron.io/veyron/veyron/lib/testutil/blackbox"
-	"veyron.io/veyron/veyron/security/caveat"
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/security/wire"
 	"veyron.io/veyron/veyron2/vlog"
@@ -473,7 +472,7 @@
 
 func TestThirdPartyCaveatMinting(t *testing.T) {
 	minter := newChain("minter")
-	cav, err := caveat.NewPublicKeyCaveat(newCaveat(proximityCaveat{}), minter.PublicID().PublicKey(), "location", security.ThirdPartyRequirements{})
+	cav, err := security.NewPublicKeyCaveat(minter.PublicID().PublicKey(), "location", security.ThirdPartyRequirements{}, newCaveat(proximityCaveat{}))
 	if err != nil {
 		t.Fatalf("security.NewPublicKeyCaveat failed: %s", err)
 	}
@@ -505,7 +504,7 @@
 		return derive(bless(id.PublicID(), googleChain, name), id)
 	}
 	mkTPCaveat := func(id security.PrivateID) security.ThirdPartyCaveat {
-		c, err := caveat.NewPublicKeyCaveat(newCaveat(alwaysValidCaveat{}), id.PublicID().PublicKey(), fmt.Sprintf("%v location", id.PublicID()), security.ThirdPartyRequirements{})
+		c, err := security.NewPublicKeyCaveat(id.PublicID().PublicKey(), fmt.Sprintf("%v location", id.PublicID()), security.ThirdPartyRequirements{}, newCaveat(alwaysValidCaveat{}))
 		if err != nil {
 			t.Fatalf("NewPublicKeyCaveat with PublicKey of: %v failed: %s", id, err)
 		}
@@ -567,7 +566,7 @@
 			ctxEmpty:         "missing discharge",
 			ctxGoogleAtOther: "security.peerBlessingsCaveat=[google] fails validation",
 			ctxExpired:       "security.unixTimeExpiryCaveat",
-			ctxInvalid:       "invalid signature",
+			ctxInvalid:       "signature verification on discharge",
 		}
 	)
 
@@ -626,7 +625,7 @@
 
 func TestThirdPartyCaveatAccessors(t *testing.T) {
 	mkTPCaveat := func(id security.PublicID) security.ThirdPartyCaveat {
-		tpCav, err := caveat.NewPublicKeyCaveat(newCaveat(alwaysValidCaveat{}), id.PublicKey(), "someLocation", security.ThirdPartyRequirements{})
+		tpCav, err := security.NewPublicKeyCaveat(id.PublicKey(), "someLocation", security.ThirdPartyRequirements{}, newCaveat(alwaysValidCaveat{}))
 		if err != nil {
 			t.Fatalf("NewPublicKeyCaveat with PublicKey of: %v failed: %s", id, err)
 		}
diff --git a/security/caveat/public_key_caveat.go b/security/caveat/public_key_caveat.go
deleted file mode 100644
index 76e8548..0000000
--- a/security/caveat/public_key_caveat.go
+++ /dev/null
@@ -1,222 +0,0 @@
-// Package caveat will be removed as the new security API takes shape before November 1, 2014.
-package caveat
-
-import (
-	"crypto/rand"
-	"crypto/sha256"
-	"encoding/binary"
-	"fmt"
-	"time"
-
-	vsecurity "veyron.io/veyron/veyron/security"
-
-	"veyron.io/veyron/veyron2/security"
-	"veyron.io/veyron/veyron2/security/wire"
-	"veyron.io/veyron/veyron2/vom"
-)
-
-// nonceLength specifies the length in bytes of the random nonce used
-// in publicKeyCaveat and publicKeyDischarge.
-//
-// TODO(ataly, ashankar): Nonce length of 16 bytes was chosen very conservatively.
-// The purpose of the random nonce is essentially to separate caveats that have
-// the same restriction and validation key (in order to prevent discharge replay).
-// Can we use 4bytes instead?.
-const nonceLength = 16
-
-// publicKeyCaveat implements security.ThirdPartyCaveat. It specifies a restriction,
-// a validation key and the location (object name) of the third-party responsible
-// for discharging the caveat. A discharge for this caveat is a signed assertion whose
-// signature can be verified using the validation key.
-//
-// TODO(ataly): This should be a VDL defined type.
-type publicKeyCaveat struct {
-	// RandNonce specifies a cryptographically random nonce (of fixed length) that
-	// uniquely identifies the caveat.
-	RandNonce []uint8
-	// DischargeMintingCaveat specifies the caveat that has to be validated
-	// before minting a discharge for a publicKeyCaveat.
-	DischargeMintingCaveat security.Caveat
-	// ValidationKey specifies the public key of the discharging-party.
-	ValidationKey wire.PublicKey
-	// ThirdPartyLocation specifies the object name of the discharging-party.
-	ThirdPartyLocation string
-	// ThirdPartyRequirements specify the information wanted in order to issue a discharge.
-	ThirdPartyRequirements security.ThirdPartyRequirements
-}
-
-// ID returns a unique 32bytes long identity for the caveat based on the random nonce
-// and SHA-256 hash of the restriction embedded in the caveat.
-//
-// TODO(ataly, ashankar): A 256bit hash is probably much stronger that what we need
-// here. Can we truncate the hash to 96bits?
-func (c *publicKeyCaveat) ID() string {
-	return id(c.RandNonce, c.DischargeMintingCaveat.ValidatorVOM)
-}
-
-func (c *publicKeyCaveat) Location() string {
-	return c.ThirdPartyLocation
-}
-
-func (c *publicKeyCaveat) String() string {
-	return fmt.Sprintf("publicKeyCaveat{DischargeMintingCaveat: (%v bytes), ThirdPartyLocation: %q}", len(c.DischargeMintingCaveat.ValidatorVOM), c.ThirdPartyLocation)
-}
-
-func (c *publicKeyCaveat) Requirements() security.ThirdPartyRequirements {
-	return c.ThirdPartyRequirements
-}
-
-func (c *publicKeyCaveat) Validate(ctx security.Context) error {
-	// Check whether the context has a dicharge matching the caveat's ID.
-	dis, ok := ctx.Discharges()[c.ID()]
-	if !ok {
-		return fmt.Errorf("missing discharge")
-	}
-
-	pkDischarge, ok := dis.(*publicKeyDischarge)
-	if !ok {
-		return fmt.Errorf("caveat of type %T cannot be validated with discharge of type %T", c, dis)
-	}
-
-	// Validate all caveats present on the discharge.
-	validators, err := vsecurity.CaveatValidators(pkDischarge.Caveats...)
-	if err != nil {
-		return err
-	}
-	for _, v := range validators {
-		if err := v.Validate(ctx); err != nil {
-			return err
-		}
-	}
-
-	// Check the discharge signature with the validation key from the caveat.
-	key, err := c.ValidationKey.Decode()
-	if err != nil {
-		return err
-	}
-	if !pkDischarge.Signature.Verify(key, pkDischarge.contentHash()) {
-		return fmt.Errorf("discharge %v has invalid signature", dis)
-	}
-	return nil
-}
-
-// publicKeyDischarge implements security.Discharge. It specifies a discharge
-// for a publicKeyCaveat, and includes a signature that can be verified with
-// the validation key of the publicKeyCaveat. Additionally, the discharge may
-// also include caveats which must all validate in order for the discharge to
-// be considered valid.
-//
-// TODO(ataly): This should be a VDL-defined type?
-type publicKeyDischarge struct {
-	// CaveatID is used to match this Discharge to the the ThirdPartyCaveat it is for.
-	CaveatID string
-
-	// Caveats under which this Discharge is valid.
-	Caveats []security.Caveat
-
-	// Signature on the contents of the discharge that can be verified using the
-	// validaton key in the publicKeycaveat this discharge is for.
-	Signature security.Signature
-}
-
-func (d *publicKeyDischarge) ID() string {
-	return d.CaveatID
-}
-
-func (d *publicKeyDischarge) ThirdPartyCaveats() []security.ThirdPartyCaveat {
-	return vsecurity.ThirdPartyCaveats(d.Caveats...)
-}
-
-func (d *publicKeyDischarge) sign(signer security.PrivateID) (err error) {
-	d.Signature, err = signer.Sign(d.contentHash())
-	return
-}
-
-func (d *publicKeyDischarge) contentHash() []byte {
-	h := sha256.New()
-	tmp := make([]byte, binary.MaxVarintLen64)
-
-	wire.WriteString(h, tmp, d.CaveatID)
-	for _, cav := range d.Caveats {
-		wire.WriteBytes(h, tmp, cav.ValidatorVOM)
-	}
-	return h.Sum(nil)
-}
-
-// NewPublicKeyCaveat returns a security.ThirdPartyCaveat which requires a
-// discharge from a principal identified by the public key 'key' and present
-// at the object name 'location'. This discharging principal is expected to
-// validate 'caveat' before issuing a discharge.
-func NewPublicKeyCaveat(caveat security.Caveat, key security.PublicKey, location string, requirements security.ThirdPartyRequirements) (security.ThirdPartyCaveat, error) {
-	nonce := make([]uint8, nonceLength)
-	if _, err := rand.Read(nonce); err != nil {
-		return nil, err
-	}
-
-	var validationKey wire.PublicKey
-	if err := validationKey.Encode(key); err != nil {
-		return nil, err
-	}
-
-	return &publicKeyCaveat{
-		RandNonce:              nonce,
-		DischargeMintingCaveat: caveat,
-		ValidationKey:          validationKey,
-		ThirdPartyLocation:     location,
-		ThirdPartyRequirements: requirements,
-	}, nil
-}
-
-// NewPublicKeyDischarge returns a new discharge for the provided 'tp'
-// after validating any restrictions specified in it under context 'ctx'.
-//
-// The ID of the discharge is the same as the ID of 'caveat', and the discharge
-// will be usable for the provided 'duration' only if:
-// (1) 'caveats' are met when using the discharge.
-// (2) 'tp' was obtained from NewPublicKeyCaveat using a key that is the same as
-// the provided signer's PublicKey.
-func NewPublicKeyDischarge(signer security.PrivateID, tp security.ThirdPartyCaveat, ctx security.Context, duration time.Duration, caveats []security.Caveat) (security.Discharge, error) {
-	pkCaveat, ok := tp.(*publicKeyCaveat)
-	if !ok {
-		return nil, fmt.Errorf("cannot mint discharges for %T", tp)
-	}
-
-	v, err := vsecurity.CaveatValidators(pkCaveat.DischargeMintingCaveat)
-	if err != nil {
-		return nil, err
-	}
-	if err := v[0].Validate(ctx); err != nil {
-		return nil, err
-	}
-
-	expiryCaveat, err := security.ExpiryCaveat(time.Now().Add(duration))
-	if err != nil {
-		return nil, err
-	}
-
-	caveats = append(caveats, expiryCaveat)
-	discharge := &publicKeyDischarge{CaveatID: tp.ID(), Caveats: caveats}
-
-	// TODO(ashankar,ataly): Should signer necessarily be the same as ctx.LocalID()?
-	// If so, need the PrivateID object corresponding to ctx.LocalID.
-	if err := discharge.sign(signer); err != nil {
-		return nil, err
-	}
-	return discharge, nil
-}
-
-// id calculates the sha256 hash of length-delimited byte slices
-func id(slices ...[]byte) string {
-	h := sha256.New()
-	tmp := make([]byte, binary.MaxVarintLen64)
-
-	for _, slice := range slices {
-		wire.WriteBytes(h, tmp, slice)
-	}
-	return string(h.Sum(nil))
-}
-
-func init() {
-	vom.Register(publicKeyCaveat{})
-	vom.Register(publicKeyDischarge{})
-}
diff --git a/services/identity/handlers/bless.go b/services/identity/handlers/bless.go
index 70d43b7..468df38 100644
--- a/services/identity/handlers/bless.go
+++ b/services/identity/handlers/bless.go
@@ -2,11 +2,14 @@
 
 import (
 	"fmt"
+	"html/template"
 	"net/http"
+	"strings"
 	"time"
 
 	"veyron.io/veyron/veyron/services/identity/util"
 	"veyron.io/veyron/veyron2/security"
+	"veyron.io/veyron/veyron2/vlog"
 )
 
 // Bless is an http.HandlerFunc that renders/processes a form that takes as
@@ -19,11 +22,11 @@
 		return
 	}
 	if r.Method != "POST" {
-		util.HTTPBadRequest(w, r, fmt.Errorf("Only GET or POST requests accepted"))
+		util.HTTPBadRequest(w, r, fmt.Errorf("only GET or POST requests accepted"))
 		return
 	}
 	if err := r.ParseForm(); err != nil {
-		util.HTTPBadRequest(w, r, fmt.Errorf("Failed to parse form: %v", err))
+		util.HTTPBadRequest(w, r, fmt.Errorf("failed to parse form: %v", err))
 		return
 	}
 	duration, err := time.ParseDuration(defaultIfEmpty(r.FormValue("duration"), "24h"))
@@ -42,7 +45,11 @@
 		return
 	}
 	name := r.FormValue("name")
-	blessed, err := blessor.Bless(blessee, name, duration, nil)
+	caveats, err := caveats(r)
+	if err != nil {
+		util.HTTPBadRequest(w, r, fmt.Errorf("failed to created caveats: ", err))
+	}
+	blessed, err := blessor.Bless(blessee, name, duration, caveats)
 	if err != nil {
 		util.HTTPBadRequest(w, r, fmt.Errorf("%q.Bless(%q, %q) failed: %v", blessor, blessee, name, err))
 		return
@@ -50,6 +57,29 @@
 	util.HTTPSend(w, blessed)
 }
 
+func caveats(r *http.Request) ([]security.Caveat, error) {
+	if err := r.ParseForm(); err != nil {
+		return nil, err
+	}
+	var caveats []security.Caveat
+	for i, cavName := range r.Form["caveat"] {
+		if cavName == "none" {
+			continue
+		}
+		args := strings.Split(r.Form[cavName][i], ",")
+		cavInfo, ok := caveatMap[cavName]
+		if !ok {
+			return nil, fmt.Errorf("unable to create caveat %s: caveat does not exist", cavName)
+		}
+		caveat, err := cavInfo.New(args...)
+		if err != nil {
+			return nil, fmt.Errorf("unable to create caveat %s(%v): cavInfo.New failed: %v", cavName, args, err)
+		}
+		caveats = append(caveats, caveat)
+	}
+	return caveats, nil
+}
+
 func decodeBlessor(r *http.Request) (security.PrivateID, error) {
 	var blessor security.PrivateID
 	b64 := r.FormValue("blessor")
@@ -74,14 +104,52 @@
 }
 
 func renderForm(w http.ResponseWriter, r *http.Request) {
-	w.Write([]byte(`
-<!doctype html>
+	w.Header().Set("Context-Type", "text/html")
+	if err := tmpl.Execute(w, caveatMap); err != nil {
+		vlog.Errorf("Unable to execute bless page template: %v", err)
+		util.HTTPServerError(w, err)
+	}
+}
+
+var tmpl = template.Must(template.New("bless").Parse(`<!doctype html>
 <html>
 <head>
 <meta charset="UTF-8">
 <title>Veyron Identity Derivation</title>
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
+<script>
+	// TODO(suharshs): Move this and other JS/CSS to an assets directory in identity server.
+	$(document).ready(function() {
+		$('.caveatInput').hide(); // Hide all the inputs at start.
+
+		// When a caveat selector changes show the corresponding input box.
+		$('body').on('change', '.caveats', function (){
+			// Grab the div encapsulating the select and the corresponding inputs.
+			var caveatSelector = $(this).parents(".caveatRow");
+			// Hide the visible inputs and show the selected one.
+			caveatSelector.find('.caveatInput').hide();
+			caveatSelector.find('#'+$(this).val()).show();
+		});
+
+		// Upon clicking the '+' button a new caveat selector should appear.
+		$('body').on('click', '.addCaveat', function() {
+			var selector = $(this).parents(".caveatRow");
+			var newSelector = selector.clone();
+			// Hide all inputs since nothing is selected in this clone.
+			newSelector.find('.caveatInput').hide();
+			selector.after(newSelector);
+			// Change the '+' button to a '-' button.
+			$(this).replaceWith('<button type="button" class="btn btn-danger btn-sm removeCaveat">-</button>')
+		});
+
+		// Upon clicking the '-' button caveats should be removed.
+		$('body').on('click', '.removeCaveat', function() {
+			$(this).parents(".caveatRow").remove();
+		});
+	});
+</script>
 </head>
 <body class="container">
 <form class="form-signin" method="POST" name="input" action="/bless/">
@@ -93,12 +161,31 @@
 <input type="text" class="form-control" name="name" placeholder="Name">
 <br/>
 <input type="text" class="form-control" name="duration" placeholder="Duration. Defaults to 24h">
+<div class="caveatRow row">
+	<br/>
+	<div class="col-md-4">
+		<select name="caveat" class="form-control caveats">
+		  <option value="none" selected="selected">Select a caveat.</option>
+		  {{ $caveatMap := . }}
+		  {{range $key, $value := $caveatMap}}
+		  <option name="{{$key}}" value="{{$key}}">{{$key}}</option>
+		  {{end}}
+		</select>
+	</div>
+	<div class="col-md-7">
+	  {{range $key, $entry := $caveatMap}}
+	  	<input type="text" id="{{$key}}" class="form-control caveatInput" name="{{$key}}" placeholder="{{$entry.Placeholder}}">
+	  {{end}}
+	</div>
+	<div class="col-md-1">
+		<button type="button" class="btn btn-info btn-sm addCaveat">+</button>
+	</div>
+</div>
 <br/>
 <button class="btn btn-lg btn-primary btn-block" type="submit">Bless</button>
 </form>
 </body>
 </html>`))
-}
 
 func defaultIfEmpty(str, def string) string {
 	if len(str) == 0 {
@@ -106,3 +193,49 @@
 	}
 	return str
 }
+
+// caveatMap is a map from Caveat name to caveat information.
+// To add to this map append
+// key = "CaveatName"
+// New = func that returns instantiation of specific caveat wrapped in security.Caveat.
+// Placeholder = the placeholder text for the html input element.
+var caveatMap = map[string]struct {
+	New         func(args ...string) (security.Caveat, error)
+	Placeholder string
+}{
+	"ExpiryCaveat": {
+		New: func(args ...string) (security.Caveat, error) {
+			if len(args) != 1 {
+				return security.Caveat{}, fmt.Errorf("must pass exactly one duration string.")
+			}
+			dur, err := time.ParseDuration(args[0])
+			if err != nil {
+				return security.Caveat{}, fmt.Errorf("parse duration failed: %v", err)
+			}
+			return security.ExpiryCaveat(time.Now().Add(dur))
+		},
+		Placeholder: "i.e. 2h45m. Valid time units are ns, us (or µs), ms, s, m, h.",
+	},
+	"MethodCaveat": {
+		New: func(args ...string) (security.Caveat, error) {
+			if len(args) < 1 {
+				return security.Caveat{}, fmt.Errorf("must pass at least one method")
+			}
+			return security.MethodCaveat(args[0], args[1:]...)
+		},
+		Placeholder: "Comma-separated method names.",
+	},
+	"PeerBlessingsCaveat": {
+		New: func(args ...string) (security.Caveat, error) {
+			if len(args) < 1 {
+				return security.Caveat{}, fmt.Errorf("must pass at least one blessing pattern")
+			}
+			var patterns []security.BlessingPattern
+			for _, arg := range args {
+				patterns = append(patterns, security.BlessingPattern(arg))
+			}
+			return security.PeerBlessingsCaveat(patterns[0], patterns[1:]...)
+		},
+		Placeholder: "Comma-separated blessing patterns.",
+	},
+}
diff --git a/services/identity/revocation/bless.go b/services/identity/revocation/bless.go
index 57dcb71..473bcd4 100644
--- a/services/identity/revocation/bless.go
+++ b/services/identity/revocation/bless.go
@@ -12,16 +12,18 @@
 
 // Bless creates a blessing on behalf of the identity server.
 func Bless(server security.PrivateID, blessee security.PublicID, email string, duration time.Duration, revocationCaveat security.ThirdPartyCaveat) (security.PublicID, error) {
+	// TODO(suharshs): Pass caveats to here when macaroon new oauth flow is complete.
+	var caveats []security.Caveat
 	if revocationCaveat != nil {
 		caveat, err := security.NewCaveat(revocationCaveat)
 		if err != nil {
 			return nil, err
 		}
-		// TODO(suharshs): Extend the duration for blessings with provided revocaionCaveats
-		return server.Bless(blessee, email, duration, []security.Caveat{caveat})
+		// revocationCaveat must be prepended because it is assumed to be first by ReadBlessAuditEntry.
+		caveats = append([]security.Caveat{caveat}, caveats...)
 	}
-	// return a blessing with a more limited duration, since there is no revocation caveat
-	return server.Bless(blessee, email, duration, nil)
+	// TODO(suharshs): Extend the duration for blessings with provided revocaionCaveats.
+	return server.Bless(blessee, email, duration, caveats)
 }
 
 type BlessingAuditEntry struct {
diff --git a/services/identity/revocation/revocation_manager.go b/services/identity/revocation/revocation_manager.go
index c05bd5e..f79e740 100644
--- a/services/identity/revocation/revocation_manager.go
+++ b/services/identity/revocation/revocation_manager.go
@@ -10,7 +10,6 @@
 	"sync"
 	"time"
 
-	"veyron.io/veyron/veyron/security/caveat"
 	"veyron.io/veyron/veyron/services/identity/util"
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/vom"
@@ -35,7 +34,7 @@
 	if err != nil {
 		return nil, err
 	}
-	cav, err := caveat.NewPublicKeyCaveat(restriction, dischargerID.PublicKey(), dischargerLocation, security.ThirdPartyRequirements{})
+	cav, err := security.NewPublicKeyCaveat(dischargerID.PublicKey(), dischargerLocation, security.ThirdPartyRequirements{}, restriction)
 	if err != nil {
 		return nil, err
 	}
diff --git a/services/mgmt/debug/dispatcher.go b/services/mgmt/debug/dispatcher.go
index a0c86cc..9c6e3b8 100644
--- a/services/mgmt/debug/dispatcher.go
+++ b/services/mgmt/debug/dispatcher.go
@@ -62,7 +62,7 @@
 		return err
 	}
 	for _, leaf := range i.leaves {
-		if ok, left := g.MatchInitialSegment(leaf); ok {
+		if ok, _, left := g.MatchInitialSegment(leaf); ok {
 			if err := i.leafGlob(call, leaf, left.String()); err != nil {
 				return err
 			}
diff --git a/services/mgmt/logreader/impl/logdir_invoker.go b/services/mgmt/logreader/impl/logdir_invoker.go
index 5beb139..ef7a60b 100644
--- a/services/mgmt/logreader/impl/logdir_invoker.go
+++ b/services/mgmt/logreader/impl/logdir_invoker.go
@@ -78,7 +78,7 @@
 		if fileName == "." || fileName == ".." {
 			continue
 		}
-		if ok, left := g.MatchInitialSegment(fileName); ok {
+		if ok, _, left := g.MatchInitialSegment(fileName); ok {
 			if err := i.globStep(path.Join(name, fileName), left, file.IsDir(), call); err != nil {
 				return err
 			}
diff --git a/services/mounttable/lib/mounttable.go b/services/mounttable/lib/mounttable.go
index 922f4c7..85936ec 100644
--- a/services/mounttable/lib/mounttable.go
+++ b/services/mounttable/lib/mounttable.go
@@ -357,7 +357,7 @@
 
 	// Recurse through the children.
 	for k, c := range n.children {
-		if ok, suffix := pattern.MatchInitialSegment(k); ok {
+		if ok, _, suffix := pattern.MatchInitialSegment(k); ok {
 			mt.globStep(c, naming.Join(name, k), suffix, context, reply)
 		}
 	}
diff --git a/services/mounttable/lib/neighborhood.go b/services/mounttable/lib/neighborhood.go
index ad66bfb..acdb46c 100644
--- a/services/mounttable/lib/neighborhood.go
+++ b/services/mounttable/lib/neighborhood.go
@@ -244,7 +244,7 @@
 	switch len(ns.elems) {
 	case 0:
 		for k, n := range nh.neighbors() {
-			if ok, _ := g.MatchInitialSegment(k); !ok {
+			if ok, _, _ := g.MatchInitialSegment(k); !ok {
 				continue
 			}
 			if err := sender.Send(types.MountEntry{Name: k, Servers: n}); err != nil {
diff --git a/services/security/discharger/revoker.go b/services/security/discharger/revoker.go
index e7c23a1..8ccea7b 100644
--- a/services/security/discharger/revoker.go
+++ b/services/security/discharger/revoker.go
@@ -9,7 +9,6 @@
 	"os"
 	"path/filepath"
 	"sync"
-	"veyron.io/veyron/veyron/security/caveat"
 	ssecurity "veyron.io/veyron/veyron/services/security"
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/security"
@@ -73,7 +72,7 @@
 	if err != nil {
 		return revocation, nil, err
 	}
-	cav, err := caveat.NewPublicKeyCaveat(restriction, dischargerID.PublicKey(), dischargerLocation, security.ThirdPartyRequirements{})
+	cav, err := security.NewPublicKeyCaveat(dischargerID.PublicKey(), dischargerLocation, security.ThirdPartyRequirements{}, restriction)
 	return revocation, cav, err
 }