syncbase.js: Inital repo and test setup.

The Makefile has tasks for running tests in both node and chrome.

The test harness starts a syncbased instance and mounts it in the test
namespace.

Currently, the tests just make RPCs directly to syncbased, mostly to
make sure the setup is working.

There is also a make task for generating syncbase vdl.js files, and
those files have been checked in to the repo in src/gen-vdl.

This CL also adds the necessary copyright headers and files.

Change-Id: I8a851539133be69660efd7df29c454af1c3ffafb
diff --git a/.gitignore b/.gitignore
index b7e2fde..8c5d116 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,5 @@
-/.v23
\ No newline at end of file
+/go/bin
+/node_modules
+/tmp
+
+/.v23
diff --git a/.jshintignore b/.jshintignore
new file mode 100644
index 0000000..6804343
--- /dev/null
+++ b/.jshintignore
@@ -0,0 +1,2 @@
+node_modules
+src/gen-vdl
diff --git a/.jshintrc b/.jshintrc
new file mode 100644
index 0000000..f846f31
--- /dev/null
+++ b/.jshintrc
@@ -0,0 +1,28 @@
+{
+  "camelcase": true,
+  "eqeqeq": true,
+  "expr": true,
+  "forin": true,
+  "freeze": true,
+  "immed": true,
+  "indent": 2,
+  "latedef": "nofunc",
+  "maxlen": 80,
+  "newcap": true,
+  "noarg": true,
+  "nonbsp": true,
+  "nonew": true,
+  "quotmark": "single",
+  "sub": true,
+  "trailing": true,
+  "undef": true,
+  "unused": "vars",
+  "esnext": true,
+  "browser": true,
+  "devel": true,
+  "node": true,
+
+  "globals": {
+    "Promise": true
+  }
+}
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..574583c
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,9 @@
+# This is the official list of Vanadium authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+
+# Names should be added to this file as:
+#   Name or Organization <email address>
+# The email address is not required for organizations.
+
+# Please keep the list sorted.
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
new file mode 100644
index 0000000..b294e50
--- /dev/null
+++ b/CONTRIBUTORS
@@ -0,0 +1,10 @@
+# People who have agreed to one of the CLAs and can contribute patches.
+# The AUTHORS file lists the copyright holders; this file
+# lists people.  For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+# https://developers.google.com/open-source/cla/individual
+# https://developers.google.com/open-source/cla/corporate
+#
+# Names should be added to this file as:
+#     Name <email address>
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..411db13
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2015 The Vanadium Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..f7f24a8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,122 @@
+SHELL := /bin/bash -euo pipefail
+export PATH := ./go/bin:$(V23_ROOT)/release/go/bin:$(V23_ROOT)/roadmap/go/bin:node_modules/.bin:$(V23_ROOT)/third_party/cout/node/bin:$(PATH)
+
+# This target causes any target files to be deleted if the target task fails.
+.DELETE_ON_ERROR:
+
+UNAME := $(shell uname)
+
+# When running browser tests on non-Darwin machines, set the --headless flag.
+# This uses Xvfb underneath the hood (inside prova => browser-launcher =>
+# headless), which is not supported on OS X.
+# See: https://github.com/kesla/node-headless/
+ifndef NOHEADLESS
+	ifneq ($(UNAME),Darwin)
+		HEADLESS := --headless
+	endif
+endif
+
+ifdef STOPONFAIL
+	STOPONFAIL := --stopOnFirstFailure
+endif
+
+ifndef NOTAP
+	TAP := --tap
+endif
+
+ifndef NOQUIT
+	QUIT := --quit
+endif
+
+ifdef XUNIT
+	TAP := --tap # TAP must be set for xunit to work
+	OUTPUT_TRANSFORM := tap-xunit
+endif
+
+ifdef BROWSER_OUTPUT
+	BROWSER_OUTPUT_LOCAL = $(BROWSER_OUTPUT)
+	ifdef OUTPUT_TRANSFORM
+		BROWSER_OUTPUT_LOCAL := >($(OUTPUT_TRANSFORM) --package=javascript.browser > $(BROWSER_OUTPUT_LOCAL))
+	endif
+	BROWSER_OUTPUT_LOCAL := | tee $(BROWSER_OUTPUT_LOCAL)
+endif
+
+PROVA_OPTS := --includeFilenameAsPackage $(TAP) $(QUIT) $(STOPONFAIL)
+
+BROWSER_OPTS := --browser --launch chrome $(HEADLESS) --log=./tmp/chrome.log
+
+.DEFAULT_GOAL := all
+
+.PHONY: all
+all:
+
+go/bin: $(shell find $(V23_ROOT) -name "*.go")
+	v23 go build -a -o $@/principal v.io/x/ref/cmd/principal
+	v23 go build -a -tags wspr -o $@/servicerunner v.io/x/ref/cmd/servicerunner
+	v23 go build -a -o $@/syncbased v.io/syncbase/x/ref/services/syncbase/syncbased
+
+.PHONY: gen-vdl
+gen-vdl:
+	v23 run vdl generate --lang=javascript --js-out-dir=src/gen-vdl v.io/syncbase/v23/services/syncbase/...
+
+node_modules: package.json
+	npm prune
+	npm install
+	# Link Vanadium from V23_ROOT.
+	rm -rf ./node_modules/vanadium
+	cd "$(V23_ROOT)/release/javascript/core" && npm link
+	npm link vanadium
+	touch node_modules
+
+# We use the same test runner as vanadium.js.  It handles starting and stopping
+# all required services (proxy, wspr, mounntabled), and runs tests in chrome
+# with prova.
+# TODO(sadovsky): Some of the deps in our package.json are needed solely for
+# runner.js. We should restructure things so that runner.js is its own npm
+# package with its own deps.
+.NOTPARALLEL: test
+.PHONY: test
+test: test-integration
+
+.NOTPARALLEL: test-integration
+.PHONY: test-integration
+test: test-integration-browser test-integration-node
+
+.PHONY: test-integration-node
+test-integration-node: export PATH := ./test:$(PATH)
+test-integration-node: go/bin lint node_modules
+	node ./node_modules/vanadium/test/integration/runner.js --services=start-syncbased.sh -- \
+	prova test/integration/test-*.js $(PROVA_OPTS) $(NODE_OUTPUT_LOCAL)
+
+.PHONY: test-integration-browser
+test-integration-browser: export PATH := ./test:$(PATH)
+test-integration-browser: go/bin lint node_modules
+	node ./node_modules/vanadium/test/integration/runner.js --services=start-syncbased.sh -- \
+	make test-integration-browser-runner
+
+# Note: runner.js sets the V23_NAMESPACE and PROXY_ADDR env vars for the
+# spawned test subprocess; we specify "make test-integration-browser-runner" as
+# the test command so that we can then reference these vars in the Vanadium
+# extension and our prova command.
+.PHONY: test-integration-browser-runner
+test-integration-browser-runner: VANADIUM_JS := $(V23_ROOT)/release/javascript/core
+test-integration-browser-runner: BROWSER_OPTS := --options="--load-extension=$(VANADIUM_JS)/extension/build-test/,--ignore-certificate-errors,--enable-logging=stderr" $(BROWSER_OPTS)
+test-integration-browser-runner:
+	$(MAKE) -C $(VANADIUM_JS)/extension clean
+	$(MAKE) -C $(VANADIUM_JS)/extension build-test
+	prova ./test/integration/test-*.js $(PROVA_OPTS) $(BROWSER_OPTS) $(BROWSER_OUTPUT_LOCAL)
+
+.PHONY: clean
+clean:
+	rm -rf \
+		go/bin \
+		node_modules \
+		tmp
+
+.PHONY: lint
+lint: node_modules
+ifdef NOLINT
+	@echo "Skipping lint - disabled by NOLINT environment variable"
+else
+	jshint .
+endif
diff --git a/PATENTS b/PATENTS
new file mode 100644
index 0000000..d52cc55
--- /dev/null
+++ b/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Vanadium project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Vanadium, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Vanadium. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Vanadium or any code incorporated within this
+implementation of Vanadium constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Vanadium
+shall terminate as of the date such litigation is filed.
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..6d6ff85
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+v23-0.1
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..d526d21
--- /dev/null
+++ b/package.json
@@ -0,0 +1,23 @@
+{
+  "name": "syncbase",
+  "version": "0.0.0",
+  "description": "",
+  "main": "index.js",
+  "dependencies": {
+    "debug": "~2.2.0"
+  },
+  "devDependencies": {
+    "jshint": "~2.7.0",
+    "prova": "aghassemi/prova#0.0.4",
+    "mkdirp": "~0.5.1",
+    "run-parallel": "~1.1.1",
+    "which": "~1.1.1",
+    "minimist": "~1.1.1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://vanadium.googlesource.com/roadmap.js.syncbase"
+  },
+  "author": "",
+  "license": "BSD"
+}
diff --git a/src/gen-vdl/v.io/syncbase/v23/services/syncbase/index.js b/src/gen-vdl/v.io/syncbase/v23/services/syncbase/index.js
new file mode 100644
index 0000000..812ab36
--- /dev/null
+++ b/src/gen-vdl/v.io/syncbase/v23/services/syncbase/index.js
@@ -0,0 +1,234 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated by the vanadium vdl tool.
+var vdl = require('vanadium').vdl;
+var makeError = require('vanadium').verror.makeError;
+var actions = require('vanadium').verror.actions;
+var canonicalize = require('vanadium').vdl.canonicalize;
+
+
+
+
+
+var access = require('./../../../../v23/security/access');
+var permissions = require('./../../../../v23/services/permissions');
+
+module.exports = {};
+
+
+
+// Types:
+
+
+
+
+// Consts:
+
+
+
+// Errors:
+
+module.exports.InvalidNameError = makeError('v.io/syncbase/v23/services/syncbase.InvalidName', actions.NO_RETRY, {
+  'en': '{1:}{2:} invalid name: {3}',
+}, [
+  vdl.types.STRING,
+]);
+
+
+
+
+// Services:
+
+  
+    
+function Service(){}
+module.exports.Service = Service;
+
+    
+      
+Service.prototype.setPermissions = function(ctx, serverCall, perms, version) {
+  throw new Error('Method SetPermissions not implemented');
+};
+    
+      
+Service.prototype.getPermissions = function(ctx, serverCall) {
+  throw new Error('Method GetPermissions not implemented');
+};
+     
+
+    
+Service.prototype._serviceDescription = {
+  name: 'Service',
+  pkgPath: 'v.io/syncbase/v23/services/syncbase',
+  doc: "// Service represents a Vanadium Syncbase service.\n// Service.Glob operates over App names.",
+  embeds: [{
+      name: 'Object',
+      pkgPath: 'v.io/v23/services/permissions',
+      doc: "// Object provides access control for Vanadium objects.\n//\n// Vanadium services implementing dynamic access control would typically embed\n// this interface and tag additional methods defined by the service with one of\n// Admin, Read, Write, Resolve etc. For example, the VDL definition of the\n// object would be:\n//\n//   package mypackage\n//\n//   import \"v.io/v23/security/access\"\n//   import \"v.io/v23/services/permissions\"\n//\n//   type MyObject interface {\n//     permissions.Object\n//     MyRead() (string, error) {access.Read}\n//     MyWrite(string) error    {access.Write}\n//   }\n//\n// If the set of pre-defined tags is insufficient, services may define their\n// own tag type and annotate all methods with this new type.\n//\n// Instead of embedding this Object interface, define SetPermissions and\n// GetPermissions in their own interface. Authorization policies will typically\n// respect annotations of a single type. For example, the VDL definition of an\n// object would be:\n//\n//  package mypackage\n//\n//  import \"v.io/v23/security/access\"\n//\n//  type MyTag string\n//\n//  const (\n//    Blue = MyTag(\"Blue\")\n//    Red  = MyTag(\"Red\")\n//  )\n//\n//  type MyObject interface {\n//    MyMethod() (string, error) {Blue}\n//\n//    // Allow clients to change access via the access.Object interface:\n//    SetPermissions(perms access.Permissions, version string) error         {Red}\n//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}\n//  }"
+    },
+    ],
+  methods: [
+    
+      
+    {
+    name: 'SetPermissions',
+    doc: "// SetPermissions replaces the current Permissions for an object.  version\n// allows for optional, optimistic concurrency control.  If non-empty,\n// version's value must come from GetPermissions.  If any client has\n// successfully called SetPermissions in the meantime, the version will be\n// stale and SetPermissions will fail.  If empty, SetPermissions performs an\n// unconditional update.\n//\n// Permissions objects are expected to be small.  It is up to the\n// implementation to define the exact limit, though it should probably be\n// around 100KB.  Large lists of principals can be represented concisely using\n// blessings.\n//\n// There is some ambiguity when calling SetPermissions on a mount point.\n// Does it affect the mount itself or does it affect the service endpoint\n// that the mount points to?  The chosen behavior is that it affects the\n// service endpoint.  To modify the mount point's Permissions, use\n// ResolveToMountTable to get an endpoint and call SetPermissions on that.\n// This means that clients must know when a name refers to a mount point to\n// change its Permissions.",
+    inArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    {
+      name: 'version',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'GetPermissions',
+    doc: "// GetPermissions returns the complete, current Permissions for an object. The\n// returned version can be passed to a subsequent call to SetPermissions for\n// optimistic concurrency control. A successful call to SetPermissions will\n// invalidate version, and the client must call GetPermissions again to get\n// the current version.",
+    inArgs: [],
+    outArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    {
+      name: 'version',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+     
+  ]
+};
+
+  
+    
+function App(){}
+module.exports.App = App;
+
+    
+      
+App.prototype.create = function(ctx, serverCall, perms) {
+  throw new Error('Method Create not implemented');
+};
+    
+      
+App.prototype.delete = function(ctx, serverCall) {
+  throw new Error('Method Delete not implemented');
+};
+    
+      
+App.prototype.setPermissions = function(ctx, serverCall, perms, version) {
+  throw new Error('Method SetPermissions not implemented');
+};
+    
+      
+App.prototype.getPermissions = function(ctx, serverCall) {
+  throw new Error('Method GetPermissions not implemented');
+};
+     
+
+    
+App.prototype._serviceDescription = {
+  name: 'App',
+  pkgPath: 'v.io/syncbase/v23/services/syncbase',
+  doc: "// App represents the data for a specific app instance (possibly a combination\n// of user, device, and app).\n// App.Glob operates over Database names.",
+  embeds: [{
+      name: 'Object',
+      pkgPath: 'v.io/v23/services/permissions',
+      doc: "// Object provides access control for Vanadium objects.\n//\n// Vanadium services implementing dynamic access control would typically embed\n// this interface and tag additional methods defined by the service with one of\n// Admin, Read, Write, Resolve etc. For example, the VDL definition of the\n// object would be:\n//\n//   package mypackage\n//\n//   import \"v.io/v23/security/access\"\n//   import \"v.io/v23/services/permissions\"\n//\n//   type MyObject interface {\n//     permissions.Object\n//     MyRead() (string, error) {access.Read}\n//     MyWrite(string) error    {access.Write}\n//   }\n//\n// If the set of pre-defined tags is insufficient, services may define their\n// own tag type and annotate all methods with this new type.\n//\n// Instead of embedding this Object interface, define SetPermissions and\n// GetPermissions in their own interface. Authorization policies will typically\n// respect annotations of a single type. For example, the VDL definition of an\n// object would be:\n//\n//  package mypackage\n//\n//  import \"v.io/v23/security/access\"\n//\n//  type MyTag string\n//\n//  const (\n//    Blue = MyTag(\"Blue\")\n//    Red  = MyTag(\"Red\")\n//  )\n//\n//  type MyObject interface {\n//    MyMethod() (string, error) {Blue}\n//\n//    // Allow clients to change access via the access.Object interface:\n//    SetPermissions(perms access.Permissions, version string) error         {Red}\n//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}\n//  }"
+    },
+    ],
+  methods: [
+    
+      
+    {
+    name: 'Create',
+    doc: "// Create creates this App.\n// If perms is nil, we inherit (copy) the Service perms.\n// Create requires the caller to have Write permission at the Service.",
+    inArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Write", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'Delete',
+    doc: "// Delete deletes this App.",
+    inArgs: [],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Write", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'SetPermissions',
+    doc: "// SetPermissions replaces the current Permissions for an object.  version\n// allows for optional, optimistic concurrency control.  If non-empty,\n// version's value must come from GetPermissions.  If any client has\n// successfully called SetPermissions in the meantime, the version will be\n// stale and SetPermissions will fail.  If empty, SetPermissions performs an\n// unconditional update.\n//\n// Permissions objects are expected to be small.  It is up to the\n// implementation to define the exact limit, though it should probably be\n// around 100KB.  Large lists of principals can be represented concisely using\n// blessings.\n//\n// There is some ambiguity when calling SetPermissions on a mount point.\n// Does it affect the mount itself or does it affect the service endpoint\n// that the mount points to?  The chosen behavior is that it affects the\n// service endpoint.  To modify the mount point's Permissions, use\n// ResolveToMountTable to get an endpoint and call SetPermissions on that.\n// This means that clients must know when a name refers to a mount point to\n// change its Permissions.",
+    inArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    {
+      name: 'version',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'GetPermissions',
+    doc: "// GetPermissions returns the complete, current Permissions for an object. The\n// returned version can be passed to a subsequent call to SetPermissions for\n// optimistic concurrency control. A successful call to SetPermissions will\n// invalidate version, and the client must call GetPermissions again to get\n// the current version.",
+    inArgs: [],
+    outArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    {
+      name: 'version',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+     
+  ]
+};
+
+   
+ 
+
+
diff --git a/src/gen-vdl/v.io/syncbase/v23/services/syncbase/nosql/index.js b/src/gen-vdl/v.io/syncbase/v23/services/syncbase/nosql/index.js
new file mode 100644
index 0000000..68a33e5
--- /dev/null
+++ b/src/gen-vdl/v.io/syncbase/v23/services/syncbase/nosql/index.js
@@ -0,0 +1,471 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated by the vanadium vdl tool.
+var vdl = require('vanadium').vdl;
+var makeError = require('vanadium').verror.makeError;
+var actions = require('vanadium').verror.actions;
+var canonicalize = require('vanadium').vdl.canonicalize;
+
+
+
+
+
+var access = require('./../../../../../v23/security/access');
+var permissions = require('./../../../../../v23/services/permissions');
+
+module.exports = {};
+
+
+
+// Types:
+var _type1 = new vdl.Type();
+var _typeBatchOptions = new vdl.Type();
+var _typePrefixPermissions = new vdl.Type();
+_type1.kind = vdl.kind.LIST;
+_type1.name = "";
+_type1.elem = _typePrefixPermissions;
+_typeBatchOptions.kind = vdl.kind.STRUCT;
+_typeBatchOptions.name = "v.io/syncbase/v23/services/syncbase/nosql.BatchOptions";
+_typeBatchOptions.fields = [{name: "Hint", type: vdl.types.STRING}, {name: "ReadOnly", type: vdl.types.BOOL}];
+_typePrefixPermissions.kind = vdl.kind.STRUCT;
+_typePrefixPermissions.name = "v.io/syncbase/v23/services/syncbase/nosql.PrefixPermissions";
+_typePrefixPermissions.fields = [{name: "Prefix", type: vdl.types.STRING}, {name: "Perms", type: new access.Permissions()._type}];
+_type1.freeze();
+_typeBatchOptions.freeze();
+_typePrefixPermissions.freeze();
+module.exports.BatchOptions = (vdl.registry.lookupOrCreateConstructor(_typeBatchOptions));
+module.exports.PrefixPermissions = (vdl.registry.lookupOrCreateConstructor(_typePrefixPermissions));
+
+
+
+
+// Consts:
+
+
+
+// Errors:
+
+module.exports.BoundToBatchError = makeError('v.io/syncbase/v23/services/syncbase/nosql.BoundToBatch', actions.NO_RETRY, {
+  'en': '{1:}{2:} bound to batch',
+}, [
+]);
+
+
+module.exports.NotBoundToBatchError = makeError('v.io/syncbase/v23/services/syncbase/nosql.NotBoundToBatch', actions.NO_RETRY, {
+  'en': '{1:}{2:} not bound to batch',
+}, [
+]);
+
+
+
+
+// Services:
+
+  
+    
+function Database(){}
+module.exports.Database = Database;
+
+    
+      
+Database.prototype.create = function(ctx, serverCall, perms) {
+  throw new Error('Method Create not implemented');
+};
+    
+      
+Database.prototype.delete = function(ctx, serverCall) {
+  throw new Error('Method Delete not implemented');
+};
+    
+      
+Database.prototype.beginBatch = function(ctx, serverCall, bo) {
+  throw new Error('Method BeginBatch not implemented');
+};
+    
+      
+Database.prototype.commit = function(ctx, serverCall) {
+  throw new Error('Method Commit not implemented');
+};
+    
+      
+Database.prototype.abort = function(ctx, serverCall) {
+  throw new Error('Method Abort not implemented');
+};
+    
+      
+Database.prototype.setPermissions = function(ctx, serverCall, perms, version) {
+  throw new Error('Method SetPermissions not implemented');
+};
+    
+      
+Database.prototype.getPermissions = function(ctx, serverCall) {
+  throw new Error('Method GetPermissions not implemented');
+};
+     
+
+    
+Database.prototype._serviceDescription = {
+  name: 'Database',
+  pkgPath: 'v.io/syncbase/v23/services/syncbase/nosql',
+  doc: "// Database represents a collection of Tables. Batches, queries, sync, watch,\n// etc. all operate at the Database level.\n// Database.Glob operates over Table names.\n//\n// TODO(sadovsky): Add Watch method.",
+  embeds: [{
+      name: 'Object',
+      pkgPath: 'v.io/v23/services/permissions',
+      doc: "// Object provides access control for Vanadium objects.\n//\n// Vanadium services implementing dynamic access control would typically embed\n// this interface and tag additional methods defined by the service with one of\n// Admin, Read, Write, Resolve etc. For example, the VDL definition of the\n// object would be:\n//\n//   package mypackage\n//\n//   import \"v.io/v23/security/access\"\n//   import \"v.io/v23/services/permissions\"\n//\n//   type MyObject interface {\n//     permissions.Object\n//     MyRead() (string, error) {access.Read}\n//     MyWrite(string) error    {access.Write}\n//   }\n//\n// If the set of pre-defined tags is insufficient, services may define their\n// own tag type and annotate all methods with this new type.\n//\n// Instead of embedding this Object interface, define SetPermissions and\n// GetPermissions in their own interface. Authorization policies will typically\n// respect annotations of a single type. For example, the VDL definition of an\n// object would be:\n//\n//  package mypackage\n//\n//  import \"v.io/v23/security/access\"\n//\n//  type MyTag string\n//\n//  const (\n//    Blue = MyTag(\"Blue\")\n//    Red  = MyTag(\"Red\")\n//  )\n//\n//  type MyObject interface {\n//    MyMethod() (string, error) {Blue}\n//\n//    // Allow clients to change access via the access.Object interface:\n//    SetPermissions(perms access.Permissions, version string) error         {Red}\n//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}\n//  }"
+    },
+    ],
+  methods: [
+    
+      
+    {
+    name: 'Create',
+    doc: "// Create creates this Database.\n// If perms is nil, we inherit (copy) the App perms.\n// Create requires the caller to have Write permission at the App.",
+    inArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Write", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'Delete',
+    doc: "// Delete deletes this Database.",
+    inArgs: [],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Write", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'BeginBatch',
+    doc: "// BeginBatch creates a new batch. It returns an App-relative name for a\n// Database handle bound to this batch. If this Database is already bound to a\n// batch, BeginBatch() will fail with ErrBoundToBatch.\n//\n// Concurrency semantics are documented in model.go.",
+    inArgs: [{
+      name: 'bo',
+      doc: "",
+      type: _typeBatchOptions
+    },
+    ],
+    outArgs: [{
+      name: '',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Read", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'Commit',
+    doc: "// Commit persists the pending changes to the database.\n// If this Database is not bound to a batch, Commit() will fail with\n// ErrNotBoundToBatch.",
+    inArgs: [],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Read", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'Abort',
+    doc: "// Abort notifies the server that any pending changes can be discarded.\n// It is not strictly required, but it may allow the server to release locks\n// or other resources sooner than if it was not called.\n// If this Database is not bound to a batch, Abort() will fail with\n// ErrNotBoundToBatch.",
+    inArgs: [],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Read", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'SetPermissions',
+    doc: "// SetPermissions replaces the current Permissions for an object.  version\n// allows for optional, optimistic concurrency control.  If non-empty,\n// version's value must come from GetPermissions.  If any client has\n// successfully called SetPermissions in the meantime, the version will be\n// stale and SetPermissions will fail.  If empty, SetPermissions performs an\n// unconditional update.\n//\n// Permissions objects are expected to be small.  It is up to the\n// implementation to define the exact limit, though it should probably be\n// around 100KB.  Large lists of principals can be represented concisely using\n// blessings.\n//\n// There is some ambiguity when calling SetPermissions on a mount point.\n// Does it affect the mount itself or does it affect the service endpoint\n// that the mount points to?  The chosen behavior is that it affects the\n// service endpoint.  To modify the mount point's Permissions, use\n// ResolveToMountTable to get an endpoint and call SetPermissions on that.\n// This means that clients must know when a name refers to a mount point to\n// change its Permissions.",
+    inArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    {
+      name: 'version',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'GetPermissions',
+    doc: "// GetPermissions returns the complete, current Permissions for an object. The\n// returned version can be passed to a subsequent call to SetPermissions for\n// optimistic concurrency control. A successful call to SetPermissions will\n// invalidate version, and the client must call GetPermissions again to get\n// the current version.",
+    inArgs: [],
+    outArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    {
+      name: 'version',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+     
+  ]
+};
+
+  
+    
+function Table(){}
+module.exports.Table = Table;
+
+    
+      
+Table.prototype.create = function(ctx, serverCall, perms) {
+  throw new Error('Method Create not implemented');
+};
+    
+      
+Table.prototype.delete = function(ctx, serverCall) {
+  throw new Error('Method Delete not implemented');
+};
+    
+      
+Table.prototype.deleteRowRange = function(ctx, serverCall, start, limit) {
+  throw new Error('Method DeleteRowRange not implemented');
+};
+    
+      
+Table.prototype.setPermissions = function(ctx, serverCall, prefix, perms) {
+  throw new Error('Method SetPermissions not implemented');
+};
+    
+      
+Table.prototype.getPermissions = function(ctx, serverCall, key) {
+  throw new Error('Method GetPermissions not implemented');
+};
+    
+      
+Table.prototype.deletePermissions = function(ctx, serverCall, prefix) {
+  throw new Error('Method DeletePermissions not implemented');
+};
+     
+
+    
+Table.prototype._serviceDescription = {
+  name: 'Table',
+  pkgPath: 'v.io/syncbase/v23/services/syncbase/nosql',
+  doc: "// Table represents a collection of Rows.\n// Table.Glob operates over the primary keys of Rows in the Table.",
+  embeds: [],
+  methods: [
+    
+      
+    {
+    name: 'Create',
+    doc: "// Create creates this Table.\n// If perms is nil, we inherit (copy) the Database perms.",
+    inArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Write", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'Delete',
+    doc: "// Delete deletes this Table.",
+    inArgs: [],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Write", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'DeleteRowRange',
+    doc: "// DeleteRowRange deletes all rows in the given range. If the last row that is\n// covered by a prefix from SetPermissions is deleted, that (prefix, perms)\n// pair is removed.\n// TODO(sadovsky): Automatic GC does not interact well with sync. This API\n// needs to be revisited.",
+    inArgs: [{
+      name: 'start',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    {
+      name: 'limit',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Write", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'SetPermissions',
+    doc: "// SetPermissions sets the permissions for all current and future rows with\n// the given prefix. If the prefix overlaps with an existing prefix, the\n// longest prefix that matches a row applies. For example:\n//     SetPermissions(ctx, Prefix(\"a/b\"), perms1)\n//     SetPermissions(ctx, Prefix(\"a/b/c\"), perms2)\n// The permissions for row \"a/b/1\" are perms1, and the permissions for row\n// \"a/b/c/1\" are perms2.\n//\n// SetPermissions will fail if called with a prefix that does not match any\n// rows.",
+    inArgs: [{
+      name: 'prefix',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    {
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'GetPermissions',
+    doc: "// GetPermissions returns an array of (prefix, perms) pairs. The array is\n// sorted from longest prefix to shortest, so element zero is the one that\n// applies to the row with the given key. The last element is always the\n// prefix \"\" which represents the table's permissions -- the array will always\n// have at least one element.",
+    inArgs: [{
+      name: 'key',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    outArgs: [{
+      name: '',
+      doc: "",
+      type: _type1
+    },
+    ],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'DeletePermissions',
+    doc: "// DeletePermissions deletes the permissions for the specified prefix. Any\n// rows covered by this prefix will use the next longest prefix's permissions\n// (see the array returned by GetPermissions).",
+    inArgs: [{
+      name: 'prefix',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+     
+  ]
+};
+
+  
+    
+function Row(){}
+module.exports.Row = Row;
+
+    
+      
+Row.prototype.get = function(ctx, serverCall) {
+  throw new Error('Method Get not implemented');
+};
+    
+      
+Row.prototype.put = function(ctx, serverCall, value) {
+  throw new Error('Method Put not implemented');
+};
+    
+      
+Row.prototype.delete = function(ctx, serverCall) {
+  throw new Error('Method Delete not implemented');
+};
+     
+
+    
+Row.prototype._serviceDescription = {
+  name: 'Row',
+  pkgPath: 'v.io/syncbase/v23/services/syncbase/nosql',
+  doc: "// Row represents a single row in a Table.\n// All access checks are performed against the most specific matching prefix\n// permissions in the Table.",
+  embeds: [],
+  methods: [
+    
+      
+    {
+    name: 'Get',
+    doc: "// Get returns the value for this Row.",
+    inArgs: [],
+    outArgs: [{
+      name: '',
+      doc: "",
+      type: vdl.types.ANY
+    },
+    ],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Read", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'Put',
+    doc: "// Put writes the given value for this Row.",
+    inArgs: [{
+      name: 'value',
+      doc: "",
+      type: vdl.types.ANY
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Write", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'Delete',
+    doc: "// Delete deletes this Row.",
+    inArgs: [],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Write", true), new access.Tag()._type), ]
+  },
+     
+  ]
+};
+
+   
+
+   
+ 
+
+
diff --git a/src/gen-vdl/v.io/v23/security/access/index.js b/src/gen-vdl/v.io/v23/security/access/index.js
new file mode 100644
index 0000000..a929339
--- /dev/null
+++ b/src/gen-vdl/v.io/v23/security/access/index.js
@@ -0,0 +1,118 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated by the vanadium vdl tool.
+var vdl = require('vanadium').vdl;
+var makeError = require('vanadium').verror.makeError;
+var actions = require('vanadium').verror.actions;
+var canonicalize = require('vanadium').vdl.canonicalize;
+
+
+
+
+
+var security = require('./..');
+
+module.exports = {};
+
+
+
+// Types:
+var _type1 = new vdl.Type();
+var _type2 = new vdl.Type();
+var _type3 = new vdl.Type();
+var _typeAccessList = new vdl.Type();
+var _typePermissions = new vdl.Type();
+var _typeTag = new vdl.Type();
+_type1.kind = vdl.kind.LIST;
+_type1.name = "";
+_type1.elem = new security.BlessingPattern()._type;
+_type2.kind = vdl.kind.LIST;
+_type2.name = "";
+_type2.elem = vdl.types.STRING;
+_type3.kind = vdl.kind.LIST;
+_type3.name = "";
+_type3.elem = new security.RejectedBlessing()._type;
+_typeAccessList.kind = vdl.kind.STRUCT;
+_typeAccessList.name = "v.io/v23/security/access.AccessList";
+_typeAccessList.fields = [{name: "In", type: _type1}, {name: "NotIn", type: _type2}];
+_typePermissions.kind = vdl.kind.MAP;
+_typePermissions.name = "v.io/v23/security/access.Permissions";
+_typePermissions.elem = _typeAccessList;
+_typePermissions.key = vdl.types.STRING;
+_typeTag.kind = vdl.kind.STRING;
+_typeTag.name = "v.io/v23/security/access.Tag";
+_type1.freeze();
+_type2.freeze();
+_type3.freeze();
+_typeAccessList.freeze();
+_typePermissions.freeze();
+_typeTag.freeze();
+module.exports.AccessList = (vdl.registry.lookupOrCreateConstructor(_typeAccessList));
+module.exports.Permissions = (vdl.registry.lookupOrCreateConstructor(_typePermissions));
+module.exports.Tag = (vdl.registry.lookupOrCreateConstructor(_typeTag));
+
+
+
+
+// Consts:
+
+  module.exports.Admin = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeTag))("Admin", true), _typeTag);
+
+  module.exports.Debug = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeTag))("Debug", true), _typeTag);
+
+  module.exports.Read = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeTag))("Read", true), _typeTag);
+
+  module.exports.Write = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeTag))("Write", true), _typeTag);
+
+  module.exports.Resolve = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeTag))("Resolve", true), _typeTag);
+
+
+
+// Errors:
+
+module.exports.TooBigError = makeError('v.io/v23/security/access.TooBig', actions.NO_RETRY, {
+  'en': '{1:}{2:} AccessList is too big',
+}, [
+]);
+
+
+module.exports.NoPermissionsError = makeError('v.io/v23/security/access.NoPermissions', actions.NO_RETRY, {
+  'en': '{1:}{2:} {3} does not have {5} access (rejected blessings: {4})',
+}, [
+  _type2,
+  _type3,
+  vdl.types.STRING,
+]);
+
+
+module.exports.AccessListMatchError = makeError('v.io/v23/security/access.AccessListMatch', actions.NO_RETRY, {
+  'en': '{1:}{2:} {3} does not match the access list (rejected blessings: {4})',
+}, [
+  _type2,
+  _type3,
+]);
+
+
+module.exports.UnenforceablePatternsError = makeError('v.io/v23/security/access.UnenforceablePatterns', actions.NO_RETRY, {
+  'en': '{1:}{2:} AccessList contains the following invalid or unrecognized patterns in the In list: {3}',
+}, [
+  _type1,
+]);
+
+
+module.exports.InvalidOpenAccessListError = makeError('v.io/v23/security/access.InvalidOpenAccessList', actions.NO_RETRY, {
+  'en': '{1:}{2:} AccessList with the pattern ... in its In list must have no other patterns in the In or NotIn lists',
+}, [
+]);
+
+
+
+
+// Services:
+
+   
+ 
+
+
diff --git a/src/gen-vdl/v.io/v23/security/index.js b/src/gen-vdl/v.io/v23/security/index.js
new file mode 100644
index 0000000..4142766
--- /dev/null
+++ b/src/gen-vdl/v.io/v23/security/index.js
@@ -0,0 +1,381 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated by the vanadium vdl tool.
+var vdl = require('vanadium').vdl;
+var makeError = require('vanadium').verror.makeError;
+var actions = require('vanadium').verror.actions;
+var canonicalize = require('vanadium').vdl.canonicalize;
+
+
+
+
+
+var time = require('./../vdlroot/time');
+var uniqueid = require('./../uniqueid');
+
+module.exports = {};
+
+
+
+// Types:
+var _type1 = new vdl.Type();
+var _type2 = new vdl.Type();
+var _type3 = new vdl.Type();
+var _type4 = new vdl.Type();
+var _type5 = new vdl.Type();
+var _type6 = new vdl.Type();
+var _type7 = new vdl.Type();
+var _type8 = new vdl.Type();
+var _typeBlessingPattern = new vdl.Type();
+var _typeCaveat = new vdl.Type();
+var _typeCaveatDescriptor = new vdl.Type();
+var _typeCertificate = new vdl.Type();
+var _typeDischargeImpetus = new vdl.Type();
+var _typeHash = new vdl.Type();
+var _typeRejectedBlessing = new vdl.Type();
+var _typeSignature = new vdl.Type();
+var _typeThirdPartyRequirements = new vdl.Type();
+var _typeWireBlessings = new vdl.Type();
+var _typeWireDischarge = new vdl.Type();
+var _typenonce = new vdl.Type();
+var _typepublicKeyDischarge = new vdl.Type();
+var _typepublicKeyThirdPartyCaveatParam = new vdl.Type();
+_type1.kind = vdl.kind.LIST;
+_type1.name = "";
+_type1.elem = _typeCaveat;
+_type2.kind = vdl.kind.LIST;
+_type2.name = "";
+_type2.elem = vdl.types.BYTE;
+_type3.kind = vdl.kind.LIST;
+_type3.name = "";
+_type3.elem = vdl.types.STRING;
+_type4.kind = vdl.kind.LIST;
+_type4.name = "";
+_type4.elem = _typeBlessingPattern;
+_type5.kind = vdl.kind.LIST;
+_type5.name = "";
+_type5.elem = vdl.types.ANY;
+_type6.kind = vdl.kind.LIST;
+_type6.name = "";
+_type6.elem = _type7;
+_type7.kind = vdl.kind.LIST;
+_type7.name = "";
+_type7.elem = _typeCertificate;
+_type8.kind = vdl.kind.LIST;
+_type8.name = "";
+_type8.elem = _typeRejectedBlessing;
+_typeBlessingPattern.kind = vdl.kind.STRING;
+_typeBlessingPattern.name = "v.io/v23/security.BlessingPattern";
+_typeCaveat.kind = vdl.kind.STRUCT;
+_typeCaveat.name = "v.io/v23/security.Caveat";
+_typeCaveat.fields = [{name: "Id", type: new uniqueid.Id()._type}, {name: "ParamVom", type: _type2}];
+_typeCaveatDescriptor.kind = vdl.kind.STRUCT;
+_typeCaveatDescriptor.name = "v.io/v23/security.CaveatDescriptor";
+_typeCaveatDescriptor.fields = [{name: "Id", type: new uniqueid.Id()._type}, {name: "ParamType", type: vdl.types.TYPEOBJECT}];
+_typeCertificate.kind = vdl.kind.STRUCT;
+_typeCertificate.name = "v.io/v23/security.Certificate";
+_typeCertificate.fields = [{name: "Extension", type: vdl.types.STRING}, {name: "PublicKey", type: _type2}, {name: "Caveats", type: _type1}, {name: "Signature", type: _typeSignature}];
+_typeDischargeImpetus.kind = vdl.kind.STRUCT;
+_typeDischargeImpetus.name = "v.io/v23/security.DischargeImpetus";
+_typeDischargeImpetus.fields = [{name: "Server", type: _type4}, {name: "Method", type: vdl.types.STRING}, {name: "Arguments", type: _type5}];
+_typeHash.kind = vdl.kind.STRING;
+_typeHash.name = "v.io/v23/security.Hash";
+_typeRejectedBlessing.kind = vdl.kind.STRUCT;
+_typeRejectedBlessing.name = "v.io/v23/security.RejectedBlessing";
+_typeRejectedBlessing.fields = [{name: "Blessing", type: vdl.types.STRING}, {name: "Err", type: vdl.types.ERROR}];
+_typeSignature.kind = vdl.kind.STRUCT;
+_typeSignature.name = "v.io/v23/security.Signature";
+_typeSignature.fields = [{name: "Purpose", type: _type2}, {name: "Hash", type: _typeHash}, {name: "R", type: _type2}, {name: "S", type: _type2}];
+_typeThirdPartyRequirements.kind = vdl.kind.STRUCT;
+_typeThirdPartyRequirements.name = "v.io/v23/security.ThirdPartyRequirements";
+_typeThirdPartyRequirements.fields = [{name: "ReportServer", type: vdl.types.BOOL}, {name: "ReportMethod", type: vdl.types.BOOL}, {name: "ReportArguments", type: vdl.types.BOOL}];
+_typeWireBlessings.kind = vdl.kind.STRUCT;
+_typeWireBlessings.name = "v.io/v23/security.WireBlessings";
+_typeWireBlessings.fields = [{name: "CertificateChains", type: _type6}];
+_typeWireDischarge.kind = vdl.kind.UNION;
+_typeWireDischarge.name = "v.io/v23/security.WireDischarge";
+_typeWireDischarge.fields = [{name: "PublicKey", type: _typepublicKeyDischarge}];
+_typenonce.kind = vdl.kind.ARRAY;
+_typenonce.name = "v.io/v23/security.nonce";
+_typenonce.len = 16;
+_typenonce.elem = vdl.types.BYTE;
+_typepublicKeyDischarge.kind = vdl.kind.STRUCT;
+_typepublicKeyDischarge.name = "v.io/v23/security.publicKeyDischarge";
+_typepublicKeyDischarge.fields = [{name: "ThirdPartyCaveatId", type: vdl.types.STRING}, {name: "Caveats", type: _type1}, {name: "Signature", type: _typeSignature}];
+_typepublicKeyThirdPartyCaveatParam.kind = vdl.kind.STRUCT;
+_typepublicKeyThirdPartyCaveatParam.name = "v.io/v23/security.publicKeyThirdPartyCaveatParam";
+_typepublicKeyThirdPartyCaveatParam.fields = [{name: "Nonce", type: _typenonce}, {name: "Caveats", type: _type1}, {name: "DischargerKey", type: _type2}, {name: "DischargerLocation", type: vdl.types.STRING}, {name: "DischargerRequirements", type: _typeThirdPartyRequirements}];
+_type1.freeze();
+_type2.freeze();
+_type3.freeze();
+_type4.freeze();
+_type5.freeze();
+_type6.freeze();
+_type7.freeze();
+_type8.freeze();
+_typeBlessingPattern.freeze();
+_typeCaveat.freeze();
+_typeCaveatDescriptor.freeze();
+_typeCertificate.freeze();
+_typeDischargeImpetus.freeze();
+_typeHash.freeze();
+_typeRejectedBlessing.freeze();
+_typeSignature.freeze();
+_typeThirdPartyRequirements.freeze();
+_typeWireBlessings.freeze();
+_typeWireDischarge.freeze();
+_typenonce.freeze();
+_typepublicKeyDischarge.freeze();
+_typepublicKeyThirdPartyCaveatParam.freeze();
+module.exports.BlessingPattern = (vdl.registry.lookupOrCreateConstructor(_typeBlessingPattern));
+module.exports.Caveat = (vdl.registry.lookupOrCreateConstructor(_typeCaveat));
+module.exports.CaveatDescriptor = (vdl.registry.lookupOrCreateConstructor(_typeCaveatDescriptor));
+module.exports.Certificate = (vdl.registry.lookupOrCreateConstructor(_typeCertificate));
+module.exports.DischargeImpetus = (vdl.registry.lookupOrCreateConstructor(_typeDischargeImpetus));
+module.exports.Hash = (vdl.registry.lookupOrCreateConstructor(_typeHash));
+module.exports.RejectedBlessing = (vdl.registry.lookupOrCreateConstructor(_typeRejectedBlessing));
+module.exports.Signature = (vdl.registry.lookupOrCreateConstructor(_typeSignature));
+module.exports.ThirdPartyRequirements = (vdl.registry.lookupOrCreateConstructor(_typeThirdPartyRequirements));
+module.exports.WireBlessings = (vdl.registry.lookupOrCreateConstructor(_typeWireBlessings));
+module.exports.WireDischarge = (vdl.registry.lookupOrCreateConstructor(_typeWireDischarge));
+module.exports.nonce = (vdl.registry.lookupOrCreateConstructor(_typenonce));
+module.exports.publicKeyDischarge = (vdl.registry.lookupOrCreateConstructor(_typepublicKeyDischarge));
+module.exports.publicKeyThirdPartyCaveatParam = (vdl.registry.lookupOrCreateConstructor(_typepublicKeyThirdPartyCaveatParam));
+
+
+
+
+// Consts:
+
+  module.exports.ConstCaveat = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeCaveatDescriptor))({
+  'id': new Uint8Array([
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+]),
+  'paramType': vdl.types.BOOL,
+}, true), _typeCaveatDescriptor);
+
+  module.exports.ExpiryCaveat = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeCaveatDescriptor))({
+  'id': new Uint8Array([
+166,
+76,
+45,
+1,
+25,
+251,
+163,
+52,
+128,
+113,
+254,
+235,
+47,
+48,
+128,
+0,
+]),
+  'paramType': new time.Time()._type,
+}, true), _typeCaveatDescriptor);
+
+  module.exports.MethodCaveat = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeCaveatDescriptor))({
+  'id': new Uint8Array([
+84,
+166,
+118,
+57,
+129,
+55,
+24,
+126,
+205,
+178,
+109,
+45,
+105,
+186,
+0,
+3,
+]),
+  'paramType': _type3,
+}, true), _typeCaveatDescriptor);
+
+  module.exports.PublicKeyThirdPartyCaveat = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeCaveatDescriptor))({
+  'id': new Uint8Array([
+121,
+114,
+206,
+23,
+74,
+123,
+169,
+63,
+121,
+84,
+125,
+118,
+156,
+145,
+128,
+0,
+]),
+  'paramType': _typepublicKeyThirdPartyCaveatParam,
+}, true), _typeCaveatDescriptor);
+
+  module.exports.PeerBlessingsCaveat = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeCaveatDescriptor))({
+  'id': new Uint8Array([
+5,
+119,
+248,
+86,
+76,
+142,
+95,
+254,
+255,
+142,
+43,
+31,
+77,
+109,
+128,
+0,
+]),
+  'paramType': _type4,
+}, true), _typeCaveatDescriptor);
+
+  module.exports.NoExtension = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeBlessingPattern))("$", true), _typeBlessingPattern);
+
+  module.exports.AllPrincipals = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeBlessingPattern))("...", true), _typeBlessingPattern);
+
+  module.exports.ChainSeparator = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(vdl.types.STRING))("/", true), vdl.types.STRING);
+
+  module.exports.SHA1Hash = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeHash))("SHA1", true), _typeHash);
+
+  module.exports.SHA256Hash = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeHash))("SHA256", true), _typeHash);
+
+  module.exports.SHA384Hash = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeHash))("SHA384", true), _typeHash);
+
+  module.exports.SHA512Hash = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(_typeHash))("SHA512", true), _typeHash);
+
+  module.exports.SignatureForMessageSigning = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(vdl.types.STRING))("S", true), vdl.types.STRING);
+
+  module.exports.SignatureForBlessingCertificates = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(vdl.types.STRING))("B", true), vdl.types.STRING);
+
+  module.exports.SignatureForDischarge = canonicalize.reduce(new (vdl.registry.lookupOrCreateConstructor(vdl.types.STRING))("D", true), vdl.types.STRING);
+
+
+
+// Errors:
+
+module.exports.CaveatNotRegisteredError = makeError('v.io/v23/security.CaveatNotRegistered', actions.NO_RETRY, {
+  'en': '{1:}{2:} no validation function registered for caveat id {3}',
+}, [
+  new uniqueid.Id()._type,
+]);
+
+
+module.exports.CaveatParamAnyError = makeError('v.io/v23/security.CaveatParamAny', actions.NO_RETRY, {
+  'en': '{1:}{2:} caveat {3} uses illegal param type any',
+}, [
+  new uniqueid.Id()._type,
+]);
+
+
+module.exports.CaveatParamTypeMismatchError = makeError('v.io/v23/security.CaveatParamTypeMismatch', actions.NO_RETRY, {
+  'en': '{1:}{2:} bad param type: caveat {3} got {4}, want {5}',
+}, [
+  new uniqueid.Id()._type,
+  vdl.types.TYPEOBJECT,
+  vdl.types.TYPEOBJECT,
+]);
+
+
+module.exports.CaveatParamCodingError = makeError('v.io/v23/security.CaveatParamCoding', actions.NO_RETRY, {
+  'en': '{1:}{2:} unable to encode/decode caveat param(type={4}) for caveat {3}: {5}',
+}, [
+  new uniqueid.Id()._type,
+  vdl.types.TYPEOBJECT,
+  vdl.types.ERROR,
+]);
+
+
+module.exports.CaveatValidationError = makeError('v.io/v23/security.CaveatValidation', actions.NO_RETRY, {
+  'en': '{1:}{2:} caveat validation failed: {3}',
+}, [
+  vdl.types.ERROR,
+]);
+
+
+module.exports.ConstCaveatValidationError = makeError('v.io/v23/security.ConstCaveatValidation', actions.NO_RETRY, {
+  'en': '{1:}{2:} false const caveat always fails validation',
+}, [
+]);
+
+
+module.exports.ExpiryCaveatValidationError = makeError('v.io/v23/security.ExpiryCaveatValidation', actions.NO_RETRY, {
+  'en': '{1:}{2:} now({4}) is after expiry({3})',
+}, [
+  new time.Time()._type,
+  new time.Time()._type,
+]);
+
+
+module.exports.MethodCaveatValidationError = makeError('v.io/v23/security.MethodCaveatValidation', actions.NO_RETRY, {
+  'en': '{1:}{2:} method {3} not in list {4}',
+}, [
+  vdl.types.STRING,
+  _type3,
+]);
+
+
+module.exports.PeerBlessingsCaveatValidationError = makeError('v.io/v23/security.PeerBlessingsCaveatValidation', actions.NO_RETRY, {
+  'en': '{1:}{2:} patterns in peer blessings caveat {4} not matched by the peer {3}',
+}, [
+  _type3,
+  _type4,
+]);
+
+
+module.exports.UnrecognizedRootError = makeError('v.io/v23/security.UnrecognizedRoot', actions.NO_RETRY, {
+  'en': '{1:}{2:} unrecognized public key {3} in root certificate{:4}',
+}, [
+  vdl.types.STRING,
+  vdl.types.ERROR,
+]);
+
+
+module.exports.AuthorizationFailedError = makeError('v.io/v23/security.AuthorizationFailed', actions.NO_RETRY, {
+  'en': '{1:}{2:} principal with blessings {3} (rejected {4}) is not authorized by principal with blessings {5}',
+}, [
+  _type3,
+  _type8,
+  _type3,
+]);
+
+
+
+
+// Services:
+
+   
+
+   
+ 
+
+
diff --git a/src/gen-vdl/v.io/v23/services/permissions/index.js b/src/gen-vdl/v.io/v23/services/permissions/index.js
new file mode 100644
index 0000000..3befb3f
--- /dev/null
+++ b/src/gen-vdl/v.io/v23/services/permissions/index.js
@@ -0,0 +1,107 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated by the vanadium vdl tool.
+var vdl = require('vanadium').vdl;
+var canonicalize = require('vanadium').vdl.canonicalize;
+
+
+
+
+
+var access = require('./../../security/access');
+
+module.exports = {};
+
+
+
+// Types:
+
+
+
+
+// Consts:
+
+
+
+// Errors:
+
+
+
+// Services:
+
+  
+    
+function Object(){}
+module.exports.Object = Object;
+
+    
+      
+Object.prototype.setPermissions = function(ctx, serverCall, perms, version) {
+  throw new Error('Method SetPermissions not implemented');
+};
+    
+      
+Object.prototype.getPermissions = function(ctx, serverCall) {
+  throw new Error('Method GetPermissions not implemented');
+};
+     
+
+    
+Object.prototype._serviceDescription = {
+  name: 'Object',
+  pkgPath: 'v.io/v23/services/permissions',
+  doc: "// Object provides access control for Vanadium objects.\n//\n// Vanadium services implementing dynamic access control would typically embed\n// this interface and tag additional methods defined by the service with one of\n// Admin, Read, Write, Resolve etc. For example, the VDL definition of the\n// object would be:\n//\n//   package mypackage\n//\n//   import \"v.io/v23/security/access\"\n//   import \"v.io/v23/services/permissions\"\n//\n//   type MyObject interface {\n//     permissions.Object\n//     MyRead() (string, error) {access.Read}\n//     MyWrite(string) error    {access.Write}\n//   }\n//\n// If the set of pre-defined tags is insufficient, services may define their\n// own tag type and annotate all methods with this new type.\n//\n// Instead of embedding this Object interface, define SetPermissions and\n// GetPermissions in their own interface. Authorization policies will typically\n// respect annotations of a single type. For example, the VDL definition of an\n// object would be:\n//\n//  package mypackage\n//\n//  import \"v.io/v23/security/access\"\n//\n//  type MyTag string\n//\n//  const (\n//    Blue = MyTag(\"Blue\")\n//    Red  = MyTag(\"Red\")\n//  )\n//\n//  type MyObject interface {\n//    MyMethod() (string, error) {Blue}\n//\n//    // Allow clients to change access via the access.Object interface:\n//    SetPermissions(perms access.Permissions, version string) error         {Red}\n//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}\n//  }",
+  embeds: [],
+  methods: [
+    
+      
+    {
+    name: 'SetPermissions',
+    doc: "// SetPermissions replaces the current Permissions for an object.  version\n// allows for optional, optimistic concurrency control.  If non-empty,\n// version's value must come from GetPermissions.  If any client has\n// successfully called SetPermissions in the meantime, the version will be\n// stale and SetPermissions will fail.  If empty, SetPermissions performs an\n// unconditional update.\n//\n// Permissions objects are expected to be small.  It is up to the\n// implementation to define the exact limit, though it should probably be\n// around 100KB.  Large lists of principals can be represented concisely using\n// blessings.\n//\n// There is some ambiguity when calling SetPermissions on a mount point.\n// Does it affect the mount itself or does it affect the service endpoint\n// that the mount points to?  The chosen behavior is that it affects the\n// service endpoint.  To modify the mount point's Permissions, use\n// ResolveToMountTable to get an endpoint and call SetPermissions on that.\n// This means that clients must know when a name refers to a mount point to\n// change its Permissions.",
+    inArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    {
+      name: 'version',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    outArgs: [],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+    
+      
+    {
+    name: 'GetPermissions',
+    doc: "// GetPermissions returns the complete, current Permissions for an object. The\n// returned version can be passed to a subsequent call to SetPermissions for\n// optimistic concurrency control. A successful call to SetPermissions will\n// invalidate version, and the client must call GetPermissions again to get\n// the current version.",
+    inArgs: [],
+    outArgs: [{
+      name: 'perms',
+      doc: "",
+      type: new access.Permissions()._type
+    },
+    {
+      name: 'version',
+      doc: "",
+      type: vdl.types.STRING
+    },
+    ],
+    inStream: null,
+    outStream: null,
+    tags: [canonicalize.reduce(new access.Tag("Admin", true), new access.Tag()._type), ]
+  },
+     
+  ]
+};
+
+   
+ 
+
+
diff --git a/src/gen-vdl/v.io/v23/uniqueid/index.js b/src/gen-vdl/v.io/v23/uniqueid/index.js
new file mode 100644
index 0000000..84dc28f
--- /dev/null
+++ b/src/gen-vdl/v.io/v23/uniqueid/index.js
@@ -0,0 +1,42 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated by the vanadium vdl tool.
+var vdl = require('vanadium').vdl;
+
+
+
+
+
+
+module.exports = {};
+
+
+
+// Types:
+var _typeId = new vdl.Type();
+_typeId.kind = vdl.kind.ARRAY;
+_typeId.name = "v.io/v23/uniqueid.Id";
+_typeId.len = 16;
+_typeId.elem = vdl.types.BYTE;
+_typeId.freeze();
+module.exports.Id = (vdl.registry.lookupOrCreateConstructor(_typeId));
+
+
+
+
+// Consts:
+
+
+
+// Errors:
+
+
+
+// Services:
+
+   
+ 
+
+
diff --git a/src/gen-vdl/v.io/v23/vdlroot/time/index.js b/src/gen-vdl/v.io/v23/vdlroot/time/index.js
new file mode 100644
index 0000000..1ca8aac
--- /dev/null
+++ b/src/gen-vdl/v.io/v23/vdlroot/time/index.js
@@ -0,0 +1,53 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated by the vanadium vdl tool.
+var vdl = require('vanadium').vdl;
+
+
+
+
+
+
+module.exports = {};
+
+
+
+// Types:
+var _typeDuration = new vdl.Type();
+var _typeTime = new vdl.Type();
+var _typeWireDeadline = new vdl.Type();
+_typeDuration.kind = vdl.kind.STRUCT;
+_typeDuration.name = "time.Duration";
+_typeDuration.fields = [{name: "Seconds", type: vdl.types.INT64}, {name: "Nanos", type: vdl.types.INT32}];
+_typeTime.kind = vdl.kind.STRUCT;
+_typeTime.name = "time.Time";
+_typeTime.fields = [{name: "Seconds", type: vdl.types.INT64}, {name: "Nanos", type: vdl.types.INT32}];
+_typeWireDeadline.kind = vdl.kind.STRUCT;
+_typeWireDeadline.name = "time.WireDeadline";
+_typeWireDeadline.fields = [{name: "FromNow", type: _typeDuration}, {name: "NoDeadline", type: vdl.types.BOOL}];
+_typeDuration.freeze();
+_typeTime.freeze();
+_typeWireDeadline.freeze();
+module.exports.Duration = (vdl.registry.lookupOrCreateConstructor(_typeDuration));
+module.exports.Time = (vdl.registry.lookupOrCreateConstructor(_typeTime));
+module.exports.WireDeadline = (vdl.registry.lookupOrCreateConstructor(_typeWireDeadline));
+
+
+
+
+// Consts:
+
+
+
+// Errors:
+
+
+
+// Services:
+
+   
+ 
+
+
diff --git a/test/integration/test-syncbase-rpcs.js b/test/integration/test-syncbase-rpcs.js
new file mode 100644
index 0000000..c2543e1
--- /dev/null
+++ b/test/integration/test-syncbase-rpcs.js
@@ -0,0 +1,80 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+var test = require('prova');
+var vanadium = require('vanadium');
+
+// TODO(nlacasse): These tests make RPCs directly to the syncbased server.
+// Most users should use the syncbase client library instead of making RPCs
+// directly. Get rid of these tests once we have tests that excercise the
+// client library.
+
+// Helper function to create a Vanadium runtime, context, and client.
+function setup(t, cb) {
+  vanadium.init(function(err, rt) {
+    if (err) {
+      return cb(err);
+    }
+
+    var ctx = rt.getContext();
+    var client = rt.newClient();
+
+    function teardown(cb) {
+      rt.close(function(err) {
+        t.error(err, 'rt.close should not error');
+        cb(null);
+      });
+    }
+
+    cb(null, {
+      ctx: ctx,
+      client: client,
+      rt: rt,
+      teardown: teardown
+    });
+  });
+}
+
+test('test bindTo syncbased', function(t) {
+  setup(t, function(err, o) {
+    if (err) {
+      return t.end(err);
+    }
+
+    o.client.bindTo(o.ctx, 'test/syncbased', function(err, syncbase) {
+      if (err) {
+        t.error(err);
+        return o.teardown(t.end);
+      }
+
+      t.ok(syncbase, 'syncbase service is defined');
+      o.teardown(t.end);
+    });
+  });
+});
+
+test('test create app', function(t) {
+  setup(t, function(err, o) {
+    if (err) {
+      return t.end(err);
+    }
+
+    var appName = 'myCoolApp';
+
+    o.client.bindTo(o.ctx, 'test/syncbased/' + appName, function(err, app) {
+      if (err) {
+        t.error(err);
+        return o.teardown(t.end);
+      }
+
+      // TODO(nlacasse): Test with a real permissions map.
+      var perms = new Map();
+
+      app.create(o.ctx, perms, function(err) {
+        t.error(err);
+        o.teardown(t.end);
+      });
+    });
+  });
+});
diff --git a/test/start-syncbased.sh b/test/start-syncbased.sh
new file mode 100755
index 0000000..f4ac91f
--- /dev/null
+++ b/test/start-syncbased.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 2015 The Vanadium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# Start syncbased and mount in the mounttable.
+
+# TODO(nlacasse): This file is needed because the javascript service-runner
+# does not allow flags or arguments to the executables it starts.  We should
+# fix service-runner to allow flags/arguments, and then have it start syncbased
+# directly with the appropriate flags.  Then we can delete this file.
+
+syncbased --name test/syncbased