This is an automated email from the ASF dual-hosted git repository.

markusthoemmes pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git


The following commit(s) were added to refs/heads/master by this push:
     new 1d79fa3  Move uuid into namespace to decouple it from authkey. (#3752)
1d79fa3 is described below

commit 1d79fa395de32c6a774efeb4f53563689e9cbb7e
Author: Martin Henke <martin.he...@web.de>
AuthorDate: Thu Jun 14 19:51:05 2018 +0200

    Move uuid into namespace to decouple it from authkey. (#3752)
    
    In many places the uuid stored in the authkey is now used as the unique way 
to identify
    a namespace. This behavior entangles the authorization mechanisms
    with other unrelated parts of the code, making changes and extensions of 
the authentication mechanism unnecessarily hard.
    
    This PR makes the uuid a member of a new namespace object containing the 
name and the
    uuid of the namespace. All references to the uuid that are not used on the 
context of authorization are using the new namespace object as source.
---
 .../logging/DockerToActivationFileLogStore.scala   |   2 +-
 .../logging/ElasticSearchLogStore.scala            |   2 +-
 .../main/scala/whisk/core/entity/EntityPath.scala  |   8 ++
 .../main/scala/whisk/core/entity/Identity.scala    |  20 ++--
 .../main/scala/whisk/core/entity/WhiskAction.scala |  13 ++-
 .../main/scala/whisk/core/entity/WhiskAuth.scala   |   6 +-
 .../controller/AuthorizedRouteDispatcher.scala     |   2 +-
 .../scala/whisk/core/controller/Namespaces.scala   |   2 +-
 .../scala/whisk/core/controller/Packages.scala     |   2 +-
 .../scala/whisk/core/controller/Triggers.scala     |   2 +-
 .../scala/whisk/core/controller/WebActions.scala   |   2 +-
 .../core/controller/actions/PrimitiveActions.scala |   6 +-
 .../core/controller/actions/SequenceActions.scala  |   2 +-
 .../core/entitlement/ActivationThrottler.scala     |   4 +-
 .../scala/whisk/core/entitlement/Entitlement.scala |  10 +-
 .../whisk/core/entitlement/RateThrottler.scala     |   2 +-
 .../core/loadBalancer/InvokerSupervision.scala     |   5 +-
 .../ShardingContainerPoolBalancer.scala            |   6 +-
 .../whisk/core/containerpool/ContainerPool.scala   |   4 +-
 .../whisk/core/containerpool/ContainerProxy.scala  |  24 +++--
 .../KubernetesInvokerAgentLogStore.scala           |   2 +-
 .../scala/whisk/core/invoker/InvokerReactive.scala |   8 +-
 .../whisk/core/invoker/NamespaceBlacklist.scala    |   2 +-
 .../logging/ElasticSearchLogStoreTests.scala       |   5 +-
 .../logging/SplunkLogStoreTests.scala              |   3 +-
 .../test/DockerToActivationFileLogStoreTests.scala |   4 +-
 .../test/DockerToActivationLogStoreTests.scala     |   7 +-
 .../containerpool/test/ContainerPoolTests.scala    |   3 +-
 .../containerpool/test/ContainerProxyTests.scala   |   6 +-
 .../core/controller/test/AuthenticateTests.scala   |  11 +-
 .../controller/test/EntitlementProviderTests.scala | 112 +++++++++++----------
 .../core/controller/test/PackagesApiTests.scala    |   2 +-
 .../core/controller/test/WebActionsApiTests.scala  |  16 ++-
 .../core/controller/test/WhiskAuthHelpers.scala    |   5 +-
 .../test/behavior/ArtifactStoreBehaviorBase.scala  |   3 +-
 .../ArtifactStoreSubjectQueryBehaviors.scala       |  52 ++++++----
 .../scala/whisk/core/entity/test/SchemaTests.scala |   3 +
 .../invoker/test/NamespaceBlacklistTests.scala     |  30 ++++--
 .../whisk/core/limits/ActionLimitsTests.scala      |   2 +-
 .../test/InvokerSupervisionTests.scala             |  17 +---
 40 files changed, 243 insertions(+), 174 deletions(-)

diff --git 
a/common/scala/src/main/scala/whisk/core/containerpool/logging/DockerToActivationFileLogStore.scala
 
b/common/scala/src/main/scala/whisk/core/containerpool/logging/DockerToActivationFileLogStore.scala
index 4be36a7..3368d2a 100644
--- 
a/common/scala/src/main/scala/whisk/core/containerpool/logging/DockerToActivationFileLogStore.scala
+++ 
b/common/scala/src/main/scala/whisk/core/containerpool/logging/DockerToActivationFileLogStore.scala
@@ -101,7 +101,7 @@ class DockerToActivationFileLogStore(system: ActorSystem, 
destinationDirectory:
     val logs = container.logs(action.limits.logs.asMegaBytes, 
action.exec.sentinelledLogs)(transid)
 
     // Adding the userId field to every written record, so any background 
process can properly correlate.
-    val userIdField = Map("namespaceId" -> user.authkey.uuid.toJson)
+    val userIdField = Map("namespaceId" -> user.namespace.uuid.toJson)
 
     val additionalMetadata = Map(
       "activationId" -> activation.activationId.asString.toJson,
diff --git 
a/common/scala/src/main/scala/whisk/core/containerpool/logging/ElasticSearchLogStore.scala
 
b/common/scala/src/main/scala/whisk/core/containerpool/logging/ElasticSearchLogStore.scala
index 26f0cd3..3340204 100644
--- 
a/common/scala/src/main/scala/whisk/core/containerpool/logging/ElasticSearchLogStore.scala
+++ 
b/common/scala/src/main/scala/whisk/core/containerpool/logging/ElasticSearchLogStore.scala
@@ -97,7 +97,7 @@ class ElasticSearchLogStore(
     EsQuery(queryString, Some(queryOrder))
   }
 
-  private def generatePath(user: Identity) = 
elasticSearchConfig.path.format(user.uuid.asString)
+  private def generatePath(user: Identity) = 
elasticSearchConfig.path.format(user.namespace.uuid.asString)
 
   override def fetchLogs(user: Identity, activation: WhiskActivation, request: 
HttpRequest): Future[ActivationLogs] = {
     val headers = extractRequiredHeaders(request.headers)
diff --git a/common/scala/src/main/scala/whisk/core/entity/EntityPath.scala 
b/common/scala/src/main/scala/whisk/core/entity/EntityPath.scala
index 0262f10..5bedddd 100644
--- a/common/scala/src/main/scala/whisk/core/entity/EntityPath.scala
+++ b/common/scala/src/main/scala/whisk/core/entity/EntityPath.scala
@@ -82,6 +82,14 @@ protected[core] class EntityPath private (private val path: 
Seq[String]) extends
    * Replaces root of this path with given namespace iff the root is
    * the default namespace.
    */
+  def resolveNamespace(newNamespace: Namespace): EntityPath = {
+    resolveNamespace(newNamespace.name)
+  }
+
+  /**
+   * Replaces root of this path with given namespace iff the root is
+   * the default namespace.
+   */
   def resolveNamespace(newNamespace: EntityName): EntityPath = {
     // check if namespace is default
     if (root.toPath == EntityPath.DEFAULT) {
diff --git a/common/scala/src/main/scala/whisk/core/entity/Identity.scala 
b/common/scala/src/main/scala/whisk/core/entity/Identity.scala
index e1b2526..f5526f9 100644
--- a/common/scala/src/main/scala/whisk/core/entity/Identity.scala
+++ b/common/scala/src/main/scala/whisk/core/entity/Identity.scala
@@ -19,7 +19,6 @@ package whisk.core.entity
 
 import scala.concurrent.Future
 import scala.util.Try
-
 import spray.json._
 import types.AuthStore
 import whisk.common.Logging
@@ -38,13 +37,17 @@ object UserLimits extends DefaultJsonProtocol {
   implicit val serdes = jsonFormat3(UserLimits.apply)
 }
 
+protected[core] case class Namespace(name: EntityName, uuid: UUID)
+
+protected[core] object Namespace extends DefaultJsonProtocol {
+  implicit val serdes = jsonFormat2(Namespace.apply)
+}
+
 protected[core] case class Identity(subject: Subject,
-                                    namespace: EntityName,
+                                    namespace: Namespace,
                                     authkey: AuthKey,
                                     rights: Set[Privilege],
-                                    limits: UserLimits = UserLimits()) {
-  def uuid = authkey.uuid
-}
+                                    limits: UserLimits = UserLimits())
 
 object Identity extends MultipleReadersSingleWriterCache[Identity, DocInfo] 
with DefaultJsonProtocol {
 
@@ -126,7 +129,12 @@ object Identity extends 
MultipleReadersSingleWriterCache[Identity, DocInfo] with
         val JsString(uuid) = value("uuid")
         val JsString(secret) = value("key")
         val JsString(namespace) = value("namespace")
-        Identity(subject, EntityName(namespace), AuthKey(UUID(uuid), 
Secret(secret)), Privilege.ALL, limits)
+        Identity(
+          subject,
+          Namespace(EntityName(namespace), UUID(uuid)),
+          AuthKey(UUID(uuid), Secret(secret)),
+          Privilege.ALL,
+          limits)
       case _ =>
         logger.error(this, s"$viewName[$key] has malformed view 
'${row.compactPrint}'")
         throw new IllegalStateException("identities view malformed")
diff --git a/common/scala/src/main/scala/whisk/core/entity/WhiskAction.scala 
b/common/scala/src/main/scala/whisk/core/entity/WhiskAction.scala
index ac6b2d0..3617ae0 100644
--- a/common/scala/src/main/scala/whisk/core/entity/WhiskAction.scala
+++ b/common/scala/src/main/scala/whisk/core/entity/WhiskAction.scala
@@ -59,7 +59,7 @@ case class WhiskActionPut(exec: Option[Exec] = None,
   /**
    * Resolves sequence components if they contain default namespace.
    */
-  protected[core] def resolve(userNamespace: EntityName): WhiskActionPut = {
+  protected[core] def resolve(userNamespace: Namespace): WhiskActionPut = {
     exec map {
       case SequenceExec(components) =>
         val newExec = SequenceExec(components map { c =>
@@ -143,6 +143,13 @@ case class WhiskAction(namespace: EntityPath,
   /**
    * Resolves sequence components if they contain default namespace.
    */
+  protected[core] def resolve(userNamespace: Namespace): WhiskAction = {
+    resolve(userNamespace.name)
+  }
+
+  /**
+   * Resolves sequence components if they contain default namespace.
+   */
   protected[core] def resolve(userNamespace: EntityName): WhiskAction = {
     exec match {
       case SequenceExec(components) =>
@@ -202,11 +209,11 @@ case class WhiskActionMetaData(namespace: EntityPath,
   /**
    * Resolves sequence components if they contain default namespace.
    */
-  protected[core] def resolve(userNamespace: EntityName): WhiskActionMetaData 
= {
+  protected[core] def resolve(userNamespace: Namespace): WhiskActionMetaData = 
{
     exec match {
       case SequenceExecMetaData(components) =>
         val newExec = SequenceExecMetaData(components map { c =>
-          FullyQualifiedEntityName(c.path.resolveNamespace(userNamespace), 
c.name)
+          
FullyQualifiedEntityName(c.path.resolveNamespace(userNamespace.name), c.name)
         })
         copy(exec = newExec).revision[WhiskActionMetaData](rev)
       case _ => this
diff --git a/common/scala/src/main/scala/whisk/core/entity/WhiskAuth.scala 
b/common/scala/src/main/scala/whisk/core/entity/WhiskAuth.scala
index be83471..2de9a86 100644
--- a/common/scala/src/main/scala/whisk/core/entity/WhiskAuth.scala
+++ b/common/scala/src/main/scala/whisk/core/entity/WhiskAuth.scala
@@ -25,18 +25,18 @@ import scala.util.Try
  * database. Each namespace has its own key which is used to determine
  * the {@ Identity} of the user calling.
  */
-protected[core] case class WhiskNamespace(name: EntityName, authkey: AuthKey)
+protected[core] case class WhiskNamespace(namespace: Namespace, authkey: 
AuthKey)
 
 protected[core] object WhiskNamespace extends DefaultJsonProtocol {
   implicit val serdes = new RootJsonFormat[WhiskNamespace] {
     def write(w: WhiskNamespace) =
-      JsObject("name" -> w.name.toJson, "uuid" -> w.authkey.uuid.toJson, "key" 
-> w.authkey.key.toJson)
+      JsObject("name" -> w.namespace.name.toJson, "uuid" -> 
w.namespace.uuid.toJson, "key" -> w.authkey.key.toJson)
 
     def read(value: JsValue) =
       Try {
         value.asJsObject.getFields("name", "uuid", "key") match {
           case Seq(JsString(n), JsString(u), JsString(k)) =>
-            WhiskNamespace(EntityName(n), AuthKey(UUID(u), Secret(k)))
+            WhiskNamespace(Namespace(EntityName(n), UUID(u)), AuthKey(UUID(u), 
Secret(k)))
         }
       } getOrElse deserializationError("namespace record malformed")
   }
diff --git 
a/core/controller/src/main/scala/whisk/core/controller/AuthorizedRouteDispatcher.scala
 
b/core/controller/src/main/scala/whisk/core/controller/AuthorizedRouteDispatcher.scala
index 9288707..2ed1a94 100644
--- 
a/core/controller/src/main/scala/whisk/core/controller/AuthorizedRouteDispatcher.scala
+++ 
b/core/controller/src/main/scala/whisk/core/controller/AuthorizedRouteDispatcher.scala
@@ -114,7 +114,7 @@ trait BasicAuthorizedRouteProvider extends Directives {
         } else {
           Messages.namespaceIllegal
         }
-      }) & extract(_ => EntityPath(if (EntityPath(ns) == EntityPath.DEFAULT) 
user.namespace.asString else ns))
+      }) & extract(_ => EntityPath(if (EntityPath(ns) == EntityPath.DEFAULT) 
user.namespace.name.asString else ns))
   }
 
   /** Validates entity name from the matched path segment. */
diff --git 
a/core/controller/src/main/scala/whisk/core/controller/Namespaces.scala 
b/core/controller/src/main/scala/whisk/core/controller/Namespaces.scala
index 0afbb40..f40a909 100644
--- a/core/controller/src/main/scala/whisk/core/controller/Namespaces.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/Namespaces.scala
@@ -42,7 +42,7 @@ trait WhiskNamespacesApi extends Directives with 
AuthenticatedRouteProvider {
    */
   override def routes(user: Identity)(implicit transid: TransactionId) = {
     (pathPrefix(collection.path) & collectionOps) {
-      complete(OK, List(user.namespace))
+      complete(OK, List(user.namespace.name))
     }
   }
 }
diff --git 
a/core/controller/src/main/scala/whisk/core/controller/Packages.scala 
b/core/controller/src/main/scala/whisk/core/controller/Packages.scala
index 509cc76..8cfbdcf 100644
--- a/core/controller/src/main/scala/whisk/core/controller/Packages.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/Packages.scala
@@ -172,7 +172,7 @@ trait WhiskPackagesApi extends WhiskCollectionAPI with 
ReferencedEntities {
       'skip.as[ListSkip] ? ListSkip(collection.defaultListSkip),
       'limit.as[ListLimit] ? ListLimit(collection.defaultListLimit),
       'count ? false) { (skip, limit, count) =>
-      val viewName = if (user.namespace.toPath == namespace) WhiskPackage.view 
else WhiskPackage.publicPackagesView
+      val viewName = if (user.namespace.name.toPath == namespace) 
WhiskPackage.view else WhiskPackage.publicPackagesView
       if (!count) {
         listEntities {
           WhiskPackage
diff --git 
a/core/controller/src/main/scala/whisk/core/controller/Triggers.scala 
b/core/controller/src/main/scala/whisk/core/controller/Triggers.scala
index 67c431c..88010d7 100644
--- a/core/controller/src/main/scala/whisk/core/controller/Triggers.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/Triggers.scala
@@ -138,7 +138,7 @@ trait WhiskTriggersApi extends WhiskCollectionAPI {
           val triggerActivationId = activationIdFactory.make()
           logging.info(this, s"[POST] trigger activation id: 
${triggerActivationId}")
           val triggerActivation = WhiskActivation(
-            namespace = user.namespace.toPath, // all activations should end 
up in the one space regardless trigger.namespace,
+            namespace = user.namespace.name.toPath, // all activations should 
end up in the one space regardless trigger.namespace,
             entityName.name,
             user.subject,
             triggerActivationId,
diff --git 
a/core/controller/src/main/scala/whisk/core/controller/WebActions.scala 
b/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
index d74815c..2878c66 100644
--- a/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
@@ -112,7 +112,7 @@ private case class Context(propertyMap: WebApiDirectives,
         .toMap
         .toJson,
       propertyMap.path -> path.toJson) ++
-      user.map(u => propertyMap.namespace -> u.namespace.asString.toJson)
+      user.map(u => propertyMap.namespace -> u.namespace.name.asString.toJson)
   }
 
   def toActionArgument(user: Option[Identity], boxQueryAndBody: Boolean): 
Map[String, JsValue] = {
diff --git 
a/core/controller/src/main/scala/whisk/core/controller/actions/PrimitiveActions.scala
 
b/core/controller/src/main/scala/whisk/core/controller/actions/PrimitiveActions.scala
index 28dbedf..135bc48 100644
--- 
a/core/controller/src/main/scala/whisk/core/controller/actions/PrimitiveActions.scala
+++ 
b/core/controller/src/main/scala/whisk/core/controller/actions/PrimitiveActions.scala
@@ -344,7 +344,7 @@ protected[actions] trait PrimitiveActions {
               // no next action, end composition execution, return to caller
               
Future.successful(ActivationResponse(activation.response.statusCode, 
Some(params.getOrElse(result))))
             case Some(next) =>
-              FullyQualifiedEntityName.resolveName(next, user.namespace) match 
{
+              FullyQualifiedEntityName.resolveName(next, user.namespace.name) 
match {
                 case Some(fqn) if session.accounting.components < 
actionSequenceLimit =>
                   tryInvokeNext(user, fqn, params, session)
 
@@ -512,7 +512,7 @@ protected[actions] trait PrimitiveActions {
 
     // create the whisk activation
     val activation = WhiskActivation(
-      namespace = user.namespace.toPath,
+      namespace = user.namespace.name.toPath,
       name = session.action.name,
       user.subject,
       activationId = session.activationId,
@@ -552,7 +552,7 @@ protected[actions] trait PrimitiveActions {
     implicit transid: TransactionId): Future[Either[ActivationId, 
WhiskActivation]] = {
     val result = Promise[Either[ActivationId, WhiskActivation]]
 
-    val docid = new DocId(WhiskEntity.qualifiedName(user.namespace.toPath, 
activationId))
+    val docid = new 
DocId(WhiskEntity.qualifiedName(user.namespace.name.toPath, activationId))
     logging.debug(this, s"action activation will block for result upto 
$totalWaitTime")
 
     // 1. Wait for the active-ack to happen. Either immediately resolve the 
promise or poll the database quickly
diff --git 
a/core/controller/src/main/scala/whisk/core/controller/actions/SequenceActions.scala
 
b/core/controller/src/main/scala/whisk/core/controller/actions/SequenceActions.scala
index 4375ee8..75ba2ac 100644
--- 
a/core/controller/src/main/scala/whisk/core/controller/actions/SequenceActions.scala
+++ 
b/core/controller/src/main/scala/whisk/core/controller/actions/SequenceActions.scala
@@ -196,7 +196,7 @@ protected[actions] trait SequenceActions {
 
     // create the whisk activation
     WhiskActivation(
-      namespace = user.namespace.toPath,
+      namespace = user.namespace.name.toPath,
       name = action.name,
       user.subject,
       activationId = activationId,
diff --git 
a/core/controller/src/main/scala/whisk/core/entitlement/ActivationThrottler.scala
 
b/core/controller/src/main/scala/whisk/core/entitlement/ActivationThrottler.scala
index b99385a..92d5434 100644
--- 
a/core/controller/src/main/scala/whisk/core/entitlement/ActivationThrottler.scala
+++ 
b/core/controller/src/main/scala/whisk/core/entitlement/ActivationThrottler.scala
@@ -42,11 +42,11 @@ class ActivationThrottler(loadBalancer: LoadBalancer, 
concurrencyLimit: Identity
    * Checks whether the operation should be allowed to proceed.
    */
   def check(user: Identity)(implicit tid: TransactionId): Future[RateLimit] = {
-    loadBalancer.activeActivationsFor(user.uuid).map { concurrentActivations =>
+    loadBalancer.activeActivationsFor(user.namespace.uuid).map { 
concurrentActivations =>
       val currentLimit = concurrencyLimit(user)
       logging.debug(
         this,
-        s"namespace = ${user.uuid.asString}, concurrent activations = 
$concurrentActivations, below limit = $currentLimit")
+        s"namespace = ${user.namespace.uuid.asString}, concurrent activations 
= $concurrentActivations, below limit = $currentLimit")
       ConcurrentRateLimit(concurrentActivations, currentLimit)
     }
   }
diff --git 
a/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala 
b/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala
index 031c267..eaf08e9 100644
--- a/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala
+++ b/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala
@@ -287,7 +287,7 @@ protected[core] abstract class EntitlementProvider(
   protected def checkPrivilege(user: Identity, right: Privilege, resources: 
Set[Resource])(
     implicit transid: TransactionId): Future[Set[(Resource, Boolean)]] = {
     // check the default namespace first, bypassing additional checks if 
permitted
-    val defaultNamespaces = Set(user.namespace.asString)
+    val defaultNamespaces = Set(user.namespace.name.asString)
     implicit val es: EntitlementProvider = this
 
     Future.sequence {
@@ -361,7 +361,7 @@ protected[core] abstract class EntitlementProvider(
   private def checkThrottleOverload(throttle: Future[RateLimit], user: 
Identity)(
     implicit transid: TransactionId): Future[Unit] = {
     throttle.flatMap { limit =>
-      val userId = user.authkey.uuid
+      val userId = user.namespace.uuid
       if (limit.ok) {
         limit match {
           case c: ConcurrentRateLimit => {
@@ -373,7 +373,7 @@ protected[core] abstract class EntitlementProvider(
                 s"controller${controllerInstance.instance}",
                 metric,
                 user.subject,
-                user.namespace.toString,
+                user.namespace.name.toString,
                 userId,
                 metric.typeName))
           }
@@ -381,7 +381,7 @@ protected[core] abstract class EntitlementProvider(
         }
         Future.successful(())
       } else {
-        logging.info(this, s"'${user.namespace}' has exceeded its throttle 
limit, ${limit.errorMsg}")
+        logging.info(this, s"'${user.namespace.name}' has exceeded its 
throttle limit, ${limit.errorMsg}")
         val metric = Metric(limit.limitName, 1)
         UserEvents.send(
           eventProducer,
@@ -389,7 +389,7 @@ protected[core] abstract class EntitlementProvider(
             s"controller${controllerInstance.instance}",
             metric,
             user.subject,
-            user.namespace.toString,
+            user.namespace.name.toString,
             userId,
             metric.typeName))
         Future.failed(RejectRequest(TooManyRequests, limit.errorMsg))
diff --git 
a/core/controller/src/main/scala/whisk/core/entitlement/RateThrottler.scala 
b/core/controller/src/main/scala/whisk/core/entitlement/RateThrottler.scala
index 9ce7216..527b699 100644
--- a/core/controller/src/main/scala/whisk/core/entitlement/RateThrottler.scala
+++ b/core/controller/src/main/scala/whisk/core/entitlement/RateThrottler.scala
@@ -45,7 +45,7 @@ class RateThrottler(description: String, maxPerMinute: 
Identity => Int)(implicit
    * @return true iff subject namespace is below allowed limit
    */
   def check(user: Identity)(implicit transid: TransactionId): RateLimit = {
-    val uuid = user.uuid // this is namespace identifier
+    val uuid = user.namespace.uuid // this is namespace identifier
     val throttle = rateMap.getOrElseUpdate(uuid, new RateInfo)
     val limit = maxPerMinute(user)
     val rate = TimedRateLimit(throttle.update(limit), limit)
diff --git 
a/core/controller/src/main/scala/whisk/core/loadBalancer/InvokerSupervision.scala
 
b/core/controller/src/main/scala/whisk/core/loadBalancer/InvokerSupervision.scala
index e33845e..152f555 100644
--- 
a/core/controller/src/main/scala/whisk/core/loadBalancer/InvokerSupervision.scala
+++ 
b/core/controller/src/main/scala/whisk/core/loadBalancer/InvokerSupervision.scala
@@ -221,13 +221,14 @@ object InvokerPool {
   /** A stub identity for invoking the test action. This does not need to be a 
valid identity. */
   val healthActionIdentity = {
     val whiskSystem = "whisk.system"
-    Identity(Subject(whiskSystem), EntityName(whiskSystem), AuthKey(UUID(), 
Secret()), Set[Privilege]())
+    val uuid = UUID()
+    Identity(Subject(whiskSystem), Namespace(EntityName(whiskSystem), uuid), 
AuthKey(uuid, Secret()), Set[Privilege]())
   }
 
   /** An action to use for monitoring invoker health. */
   def healthAction(i: InstanceId) = 
ExecManifest.runtimesManifest.resolveDefaultRuntime("nodejs:6").map { manifest 
=>
     new WhiskAction(
-      namespace = healthActionIdentity.namespace.toPath,
+      namespace = healthActionIdentity.namespace.name.toPath,
       name = EntityName(s"invokerHealthTestAction${i.toInt}"),
       exec = CodeExecAsString(manifest, """function main(params) { return 
params; }""", None))
   }
diff --git 
a/core/controller/src/main/scala/whisk/core/loadBalancer/ShardingContainerPoolBalancer.scala
 
b/core/controller/src/main/scala/whisk/core/loadBalancer/ShardingContainerPoolBalancer.scala
index 7e817e7..eb95936 100644
--- 
a/core/controller/src/main/scala/whisk/core/loadBalancer/ShardingContainerPoolBalancer.scala
+++ 
b/core/controller/src/main/scala/whisk/core/loadBalancer/ShardingContainerPoolBalancer.scala
@@ -138,7 +138,7 @@ class ShardingContainerPoolBalancer(config: WhiskConfig, 
controllerInstance: Ins
       if (!action.exec.pull) (schedulingState.managedInvokers, 
schedulingState.managedStepSizes)
       else (schedulingState.blackboxInvokers, 
schedulingState.blackboxStepSizes)
     val chosen = if (invokersToUse.nonEmpty) {
-      val hash = 
ShardingContainerPoolBalancer.generateHash(msg.user.namespace, 
action.fullyQualifiedName(false))
+      val hash = 
ShardingContainerPoolBalancer.generateHash(msg.user.namespace.name, 
action.fullyQualifiedName(false))
       val homeInvoker = hash % invokersToUse.size
       val stepSize = stepSizes(hash % stepSizes.size)
       ShardingContainerPoolBalancer.schedule(invokersToUse, 
schedulingState.invokerSlots, homeInvoker, stepSize)
@@ -162,7 +162,7 @@ class ShardingContainerPoolBalancer(config: WhiskConfig, 
controllerInstance: Ins
                               instance: InstanceId): ActivationEntry = {
 
     totalActivations.increment()
-    activationsPerNamespace.getOrElseUpdate(msg.user.uuid, new 
LongAdder()).increment()
+    activationsPerNamespace.getOrElseUpdate(msg.user.namespace.uuid, new 
LongAdder()).increment()
 
     val timeout = action.limits.timeout.duration.max(TimeLimit.STD_DURATION) + 
1.minute
     // Install a timeout handler for the catastrophic case where an active ack 
is not received at all
@@ -178,7 +178,7 @@ class ShardingContainerPoolBalancer(config: WhiskConfig, 
controllerInstance: Ins
         // please note: timeoutHandler.cancel must be called on all 
non-timeout paths, e.g. Success
         ActivationEntry(
           msg.activationId,
-          msg.user.uuid,
+          msg.user.namespace.uuid,
           instance,
           timeoutHandler,
           Promise[Either[ActivationId, WhiskActivation]]())
diff --git 
a/core/invoker/src/main/scala/whisk/core/containerpool/ContainerPool.scala 
b/core/invoker/src/main/scala/whisk/core/containerpool/ContainerPool.scala
index d26ebdc..90f5d73 100644
--- a/core/invoker/src/main/scala/whisk/core/containerpool/ContainerPool.scala
+++ b/core/invoker/src/main/scala/whisk/core/containerpool/ContainerPool.scala
@@ -95,7 +95,7 @@ class ContainerPool(childFactory: ActorRefFactory => ActorRef,
 
         // Schedule a job to a warm container
         ContainerPool
-          .schedule(r.action, r.msg.user.namespace, freePool)
+          .schedule(r.action, r.msg.user.namespace.name, freePool)
           .map(container => {
             (container, "warm")
           })
@@ -141,7 +141,7 @@ class ContainerPool(childFactory: ActorRefFactory => 
ActorRef,
               this,
               s"Rescheduling Run message, too many message in the pool, 
freePoolSize: ${freePool.size}, " +
                 s"busyPoolSize: ${busyPool.size}, maxActiveContainers 
${poolConfig.maxActiveContainers}, " +
-                s"userNamespace: ${r.msg.user.namespace}, action: 
${r.action}")(r.msg.transid)
+                s"userNamespace: ${r.msg.user.namespace.name}, action: 
${r.action}")(r.msg.transid)
             Some(logMessageInterval.fromNow)
           } else {
             r.retryLogDeadline
diff --git 
a/core/invoker/src/main/scala/whisk/core/containerpool/ContainerProxy.scala 
b/core/invoker/src/main/scala/whisk/core/containerpool/ContainerProxy.scala
index b75ad72..0a7c1ac 100644
--- a/core/invoker/src/main/scala/whisk/core/containerpool/ContainerProxy.scala
+++ b/core/invoker/src/main/scala/whisk/core/containerpool/ContainerProxy.scala
@@ -132,7 +132,7 @@ class ContainerProxy(
       // create a new container
       val container = factory(
         job.msg.transid,
-        ContainerProxy.containerName(instance, job.msg.user.namespace.name, 
job.action.name.name),
+        ContainerProxy.containerName(instance, 
job.msg.user.namespace.name.asString, job.action.name.asString),
         job.action.exec.image,
         job.action.exec.pull,
         job.action.limits.memory.megabytes.MB,
@@ -161,13 +161,18 @@ class ContainerProxy(
             // implicitly via a FailureMessage which will be processed later 
when the state
             // transitions to Running
             val activation = ContainerProxy.constructWhiskActivation(job, 
None, Interval.zero, response)
-            sendActiveAck(transid, activation, job.msg.blocking, 
job.msg.rootControllerIndex, job.msg.user.authkey.uuid)
+            sendActiveAck(
+              transid,
+              activation,
+              job.msg.blocking,
+              job.msg.rootControllerIndex,
+              job.msg.user.namespace.uuid)
             storeActivation(transid, activation)
         }
         .flatMap { container =>
           // now attempt to inject the user code and run the action
           initializeAndRun(container, job)
-            .map(_ => WarmedData(container, job.msg.user.namespace, 
job.action, Instant.now))
+            .map(_ => WarmedData(container, job.msg.user.namespace.name, 
job.action, Instant.now))
         }
         .pipeTo(self)
 
@@ -192,7 +197,7 @@ class ContainerProxy(
     case Event(job: Run, data: PreWarmedData) =>
       implicit val transid = job.msg.transid
       initializeAndRun(data.container, job)
-        .map(_ => WarmedData(data.container, job.msg.user.namespace, 
job.action, Instant.now))
+        .map(_ => WarmedData(data.container, job.msg.user.namespace.name, 
job.action, Instant.now))
         .pipeTo(self)
 
       goto(Running)
@@ -228,7 +233,7 @@ class ContainerProxy(
     case Event(job: Run, data: WarmedData) =>
       implicit val transid = job.msg.transid
       initializeAndRun(data.container, job)
-        .map(_ => WarmedData(data.container, job.msg.user.namespace, 
job.action, Instant.now))
+        .map(_ => WarmedData(data.container, job.msg.user.namespace.name, 
job.action, Instant.now))
         .pipeTo(self)
 
       goto(Running)
@@ -261,7 +266,7 @@ class ContainerProxy(
             self ! job
         }
         .flatMap(_ => initializeAndRun(data.container, job))
-        .map(_ => WarmedData(data.container, job.msg.user.namespace, 
job.action, Instant.now))
+        .map(_ => WarmedData(data.container, job.msg.user.namespace.name, 
job.action, Instant.now))
         .pipeTo(self)
 
       goto(Running)
@@ -351,7 +356,7 @@ class ContainerProxy(
 
         val environment = JsObject(
           "api_key" -> job.msg.user.authkey.compact.toJson,
-          "namespace" -> job.msg.user.namespace.toJson,
+          "namespace" -> job.msg.user.namespace.name.toJson,
           "action_name" -> job.msg.action.qualifiedNameWithLeadingSlash.toJson,
           "activation_id" -> job.msg.activationId.toString.toJson,
           // compute deadline on invoker side avoids discrepancies inside 
container
@@ -380,7 +385,8 @@ class ContainerProxy(
       }
 
     // Sending active ack. Entirely asynchronous and not waited upon.
-    activation.foreach(sendActiveAck(tid, _, job.msg.blocking, 
job.msg.rootControllerIndex, job.msg.user.authkey.uuid))
+    activation.foreach(
+      sendActiveAck(tid, _, job.msg.blocking, job.msg.rootControllerIndex, 
job.msg.user.namespace.uuid))
 
     // Adds logs to the raw activation.
     val activationWithLogs: Future[Either[ActivationLogReadingError, 
WhiskActivation]] = activation
@@ -487,7 +493,7 @@ object ContainerProxy {
 
     WhiskActivation(
       activationId = job.msg.activationId,
-      namespace = job.msg.user.namespace.toPath,
+      namespace = job.msg.user.namespace.name.toPath,
       subject = job.msg.user.subject,
       cause = job.msg.cause,
       name = job.action.name,
diff --git 
a/core/invoker/src/main/scala/whisk/core/containerpool/kubernetes/KubernetesInvokerAgentLogStore.scala
 
b/core/invoker/src/main/scala/whisk/core/containerpool/kubernetes/KubernetesInvokerAgentLogStore.scala
index 17f8363..ec3d645 100644
--- 
a/core/invoker/src/main/scala/whisk/core/containerpool/kubernetes/KubernetesInvokerAgentLogStore.scala
+++ 
b/core/invoker/src/main/scala/whisk/core/containerpool/kubernetes/KubernetesInvokerAgentLogStore.scala
@@ -51,7 +51,7 @@ class KubernetesInvokerAgentLogStore(system: ActorSystem) 
extends LogDriverLogSt
     val sentinelledLogs = action.exec.sentinelledLogs
 
     // Add the userId field to every written record, so any background process 
can properly correlate.
-    val userIdField = Map("namespaceId" -> user.authkey.uuid.toJson)
+    val userIdField = Map("namespaceId" -> user.namespace.uuid.toJson)
 
     val additionalMetadata = Map(
       "activationId" -> activation.activationId.asString.toJson,
diff --git 
a/core/invoker/src/main/scala/whisk/core/invoker/InvokerReactive.scala 
b/core/invoker/src/main/scala/whisk/core/invoker/InvokerReactive.scala
index 4d28382..4ad6bbf 100644
--- a/core/invoker/src/main/scala/whisk/core/invoker/InvokerReactive.scala
+++ b/core/invoker/src/main/scala/whisk/core/invoker/InvokerReactive.scala
@@ -234,7 +234,7 @@ class InvokerReactive(
 
                 val activation = generateFallbackActivation(msg, response)
                 activationFeed ! MessageFeed.Processed
-                ack(msg.transid, activation, msg.blocking, 
msg.rootControllerIndex, msg.user.authkey.uuid)
+                ack(msg.transid, activation, msg.blocking, 
msg.rootControllerIndex, msg.user.namespace.uuid)
                 store(msg.transid, activation)
                 Future.successful(())
             }
@@ -244,8 +244,8 @@ class InvokerReactive(
           activationFeed ! MessageFeed.Processed
           val activation =
             generateFallbackActivation(msg, 
ActivationResponse.applicationError(Messages.namespacesBlacklisted))
-          ack(msg.transid, activation, false, msg.rootControllerIndex, 
msg.user.authkey.uuid)
-          logging.warn(this, s"namespace ${msg.user.namespace} was blocked in 
invoker.")
+          ack(msg.transid, activation, false, msg.rootControllerIndex, 
msg.user.namespace.uuid)
+          logging.warn(this, s"namespace ${msg.user.namespace.name} was 
blocked in invoker.")
           Future.successful(())
         }
       }
@@ -268,7 +268,7 @@ class InvokerReactive(
 
     WhiskActivation(
       activationId = msg.activationId,
-      namespace = msg.user.namespace.toPath,
+      namespace = msg.user.namespace.name.toPath,
       subject = msg.user.subject,
       cause = msg.cause,
       name = msg.action.name,
diff --git 
a/core/invoker/src/main/scala/whisk/core/invoker/NamespaceBlacklist.scala 
b/core/invoker/src/main/scala/whisk/core/invoker/NamespaceBlacklist.scala
index 4f4336e..5da3407 100644
--- a/core/invoker/src/main/scala/whisk/core/invoker/NamespaceBlacklist.scala
+++ b/core/invoker/src/main/scala/whisk/core/invoker/NamespaceBlacklist.scala
@@ -44,7 +44,7 @@ class NamespaceBlacklist(authStore: AuthStore) {
    * @param identity which invoked the action.
    * @return whether or not the current identity is considered blacklisted
    */
-  def isBlacklisted(identity: Identity): Boolean = 
blacklist.contains(identity.namespace.name)
+  def isBlacklisted(identity: Identity): Boolean = 
blacklist.contains(identity.namespace.name.asString)
 
   /** Refreshes the current blacklist from the database. */
   def refreshBlacklist()(implicit ec: ExecutionContext, tid: TransactionId): 
Future[Set[String]] = {
diff --git 
a/tests/src/test/scala/whisk/core/containerpool/logging/ElasticSearchLogStoreTests.scala
 
b/tests/src/test/scala/whisk/core/containerpool/logging/ElasticSearchLogStoreTests.scala
index ebd8c8c..7ed3910 100644
--- 
a/tests/src/test/scala/whisk/core/containerpool/logging/ElasticSearchLogStoreTests.scala
+++ 
b/tests/src/test/scala/whisk/core/containerpool/logging/ElasticSearchLogStoreTests.scala
@@ -52,7 +52,8 @@ class ElasticSearchLogStoreTests
   implicit val ec: ExecutionContext = system.dispatcher
   implicit val materializer: ActorMaterializer = ActorMaterializer()
 
-  private val user = Identity(Subject(), EntityName("testSpace"), AuthKey(), 
Set())
+  private val uuid = UUID()
+  private val user = Identity(Subject(), Namespace(EntityName("testSpace"), 
uuid), AuthKey(uuid, Secret()), Set())
   private val activationId = ActivationId.generate()
 
   private val defaultLogSchema =
@@ -166,7 +167,7 @@ class ElasticSearchLogStoreTests
       ElasticSearchLogStoreConfig("https", "host", 443, 
"/elasticsearch/logstash-%s*/_search", defaultLogSchema)
     val httpRequest = HttpRequest(
       POST,
-      Uri(s"/elasticsearch/logstash-${user.uuid.asString}*/_search"),
+      Uri(s"/elasticsearch/logstash-${user.namespace.uuid.asString}*/_search"),
       List(Accept(MediaTypes.`application/json`)),
       HttpEntity(ContentTypes.`application/json`, defaultPayload))
     val esLogStore = new ElasticSearchLogStore(
diff --git 
a/tests/src/test/scala/whisk/core/containerpool/logging/SplunkLogStoreTests.scala
 
b/tests/src/test/scala/whisk/core/containerpool/logging/SplunkLogStoreTests.scala
index d77f610..a087a86 100644
--- 
a/tests/src/test/scala/whisk/core/containerpool/logging/SplunkLogStoreTests.scala
+++ 
b/tests/src/test/scala/whisk/core/containerpool/logging/SplunkLogStoreTests.scala
@@ -68,7 +68,8 @@ class SplunkLogStoreTests
   val startTime = "2007-12-03T10:15:30Z"
   val endTime = "2007-12-03T10:15:45Z"
   val endTimePlus5 = "2007-12-03T10:15:50Z" //queried end time range is 
endTime+5
-  val user = Identity(Subject(), EntityName("testSpace"), AuthKey(), Set())
+  val uuid = UUID()
+  val user = Identity(Subject(), Namespace(EntityName("testSpace"), uuid), 
AuthKey(uuid, Secret()), Set())
   val request = HttpRequest(
     method = POST,
     uri = "https://some.url";,
diff --git 
a/tests/src/test/scala/whisk/core/containerpool/logging/test/DockerToActivationFileLogStoreTests.scala
 
b/tests/src/test/scala/whisk/core/containerpool/logging/test/DockerToActivationFileLogStoreTests.scala
index 6f80a92..e539eeb 100644
--- 
a/tests/src/test/scala/whisk/core/containerpool/logging/test/DockerToActivationFileLogStoreTests.scala
+++ 
b/tests/src/test/scala/whisk/core/containerpool/logging/test/DockerToActivationFileLogStoreTests.scala
@@ -57,7 +57,7 @@ class DockerToActivationFileLogStoreTests
   }
 
   def toLoggedActivation(activation: WhiskActivation): String = {
-    JsObject(activation.toJson.fields ++ Map("namespaceId" -> 
user.authkey.uuid.asString.toJson)).compactPrint + "\n"
+    JsObject(activation.toJson.fields ++ Map("namespaceId" -> 
user.namespace.uuid.asString.toJson)).compactPrint + "\n"
   }
 
   behavior of "DockerCouchDbFileLogStore"
@@ -77,7 +77,7 @@ class DockerToActivationFileLogStoreTests
     await(collected) shouldBe 
ActivationLogs(logs.map(_.toFormattedString).toVector)
     logs.foreach { line =>
       testActor.expectMsg(
-        toLoggedEvent(line, user.authkey.uuid, activation.activationId, 
action.fullyQualifiedName(false)))
+        toLoggedEvent(line, user.namespace.uuid, activation.activationId, 
action.fullyQualifiedName(false)))
     }
 
     // Last message should be the full activation
diff --git 
a/tests/src/test/scala/whisk/core/containerpool/logging/test/DockerToActivationLogStoreTests.scala
 
b/tests/src/test/scala/whisk/core/containerpool/logging/test/DockerToActivationLogStoreTests.scala
index ae5249e..4df8bde 100644
--- 
a/tests/src/test/scala/whisk/core/containerpool/logging/test/DockerToActivationLogStoreTests.scala
+++ 
b/tests/src/test/scala/whisk/core/containerpool/logging/test/DockerToActivationLogStoreTests.scala
@@ -40,12 +40,13 @@ import scala.concurrent.duration._
 class DockerToActivationLogStoreTests extends FlatSpec with Matchers with 
WskActorSystem with StreamLogging {
   def await[T](future: Future[T]) = Await.result(future, 1.minute)
 
-  val user = Identity(Subject(), EntityName("testSpace"), AuthKey(), Set())
+  val uuid = UUID()
+  val user = Identity(Subject(), Namespace(EntityName("testSpace"), uuid), 
AuthKey(uuid, Secret()), Set())
   val exec = CodeExecAsString(RuntimeManifest("actionKind", 
ImageName("testImage")), "testCode", None)
-  val action = ExecutableWhiskAction(user.namespace.toPath, 
EntityName("actionName"), exec)
+  val action = ExecutableWhiskAction(user.namespace.name.toPath, 
EntityName("actionName"), exec)
   val activation =
     WhiskActivation(
-      user.namespace.toPath,
+      user.namespace.name.toPath,
       action.name,
       user.subject,
       ActivationId.generate(),
diff --git 
a/tests/src/test/scala/whisk/core/containerpool/test/ContainerPoolTests.scala 
b/tests/src/test/scala/whisk/core/containerpool/test/ContainerPoolTests.scala
index 3fe1253..46f4559 100644
--- 
a/tests/src/test/scala/whisk/core/containerpool/test/ContainerPoolTests.scala
+++ 
b/tests/src/test/scala/whisk/core/containerpool/test/ContainerPoolTests.scala
@@ -71,11 +71,12 @@ class ContainerPoolTests
 
   /** Creates a `Run` message */
   def createRunMessage(action: ExecutableWhiskAction, invocationNamespace: 
EntityName) = {
+    val uuid = UUID()
     val message = ActivationMessage(
       TransactionId.testing,
       action.fullyQualifiedName(true),
       action.rev,
-      Identity(Subject(), invocationNamespace, AuthKey(), Set()),
+      Identity(Subject(), Namespace(invocationNamespace, uuid), AuthKey(uuid, 
Secret()), Set()),
       ActivationId.generate(),
       InstanceId(0),
       blocking = false,
diff --git 
a/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala 
b/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala
index 205834e..8bbf806 100644
--- 
a/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala
+++ 
b/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala
@@ -79,11 +79,13 @@ class ContainerProxyTests
     Interval(now, now.plusMillis(200))
   }
 
+  val uuid = UUID()
+
   val message = ActivationMessage(
     messageTransId,
     action.fullyQualifiedName(true),
     action.rev,
-    Identity(Subject(), invocationNamespace, AuthKey(), Set()),
+    Identity(Subject(), Namespace(invocationNamespace, uuid), AuthKey(uuid, 
Secret()), Set()),
     ActivationId.generate(),
     InstanceId(0),
     blocking = false,
@@ -760,7 +762,7 @@ class ContainerProxyTests
       implicit transid: TransactionId): Future[(Interval, ActivationResponse)] 
= {
       runCount += 1
       environment.fields("api_key") shouldBe message.user.authkey.toJson
-      environment.fields("namespace") shouldBe invocationNamespace.toJson
+      environment.fields("namespace") shouldBe invocationNamespace.name.toJson
       environment.fields("action_name") shouldBe 
message.action.qualifiedNameWithLeadingSlash.toJson
       environment.fields("activation_id") shouldBe message.activationId.toJson
       val deadline = 
Instant.ofEpochMilli(environment.fields("deadline").convertTo[String].toLong)
diff --git 
a/tests/src/test/scala/whisk/core/controller/test/AuthenticateTests.scala 
b/tests/src/test/scala/whisk/core/controller/test/AuthenticateTests.scala
index 3c4628b..8a6d254 100644
--- a/tests/src/test/scala/whisk/core/controller/test/AuthenticateTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/AuthenticateTests.scala
@@ -48,9 +48,12 @@ class AuthenticateTests extends ControllerTestCommon with 
Authenticate {
     implicit val tid = transid()
     val subject = Subject()
 
+    val uuid1 = UUID()
+    val uuid2 = UUID()
+
     val namespaces = Set(
-      WhiskNamespace(MakeName.next("authenticatev_tests"), AuthKey()),
-      WhiskNamespace(MakeName.next("authenticatev_tests"), AuthKey()))
+      WhiskNamespace(Namespace(MakeName.next("authenticatev_tests"), uuid1), 
AuthKey(uuid1, Secret())),
+      WhiskNamespace(Namespace(MakeName.next("authenticatev_tests"), uuid2), 
AuthKey(uuid2, Secret())))
     val entry = WhiskAuth(subject, namespaces)
     put(authStore, entry) // this test entry is reclaimed when the test 
completes
 
@@ -60,7 +63,7 @@ class AuthenticateTests extends ControllerTestCommon with 
Authenticate {
         waitOnView(authStore, ns.authkey, 1) // wait for the view to be updated
         val pass = BasicHttpCredentials(ns.authkey.uuid.asString, 
ns.authkey.key.asString)
         val user = Await.result(validateCredentials(Some(pass)), dbOpTimeout)
-        user.get shouldBe Identity(subject, ns.name, ns.authkey, Privilege.ALL)
+        user.get shouldBe Identity(subject, ns.namespace, ns.authkey, 
Privilege.ALL)
 
         // first lookup should have been from datastore
         stream.toString should include(s"serving from datastore: 
${CacheKey(ns.authkey)}")
@@ -68,7 +71,7 @@ class AuthenticateTests extends ControllerTestCommon with 
Authenticate {
 
         // repeat query, now should be served from cache
         val cachedUser = 
Await.result(validateCredentials(Some(pass))(transid()), dbOpTimeout)
-        cachedUser.get shouldBe Identity(subject, ns.name, ns.authkey, 
Privilege.ALL)
+        cachedUser.get shouldBe Identity(subject, ns.namespace, ns.authkey, 
Privilege.ALL)
 
         stream.toString should include(s"serving from cache: 
${CacheKey(ns.authkey)}")
         stream.reset()
diff --git 
a/tests/src/test/scala/whisk/core/controller/test/EntitlementProviderTests.scala
 
b/tests/src/test/scala/whisk/core/controller/test/EntitlementProviderTests.scala
index 65e810b..f95c5c0 100644
--- 
a/tests/src/test/scala/whisk/core/controller/test/EntitlementProviderTests.scala
+++ 
b/tests/src/test/scala/whisk/core/controller/test/EntitlementProviderTests.scala
@@ -58,7 +58,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
   it should "authorize a user to only read from their collection" in {
     implicit val tid = transid()
     val collections = Seq(ACTIONS, RULES, TRIGGERS, PACKAGES, ACTIVATIONS, 
NAMESPACES)
-    val resources = collections map { Resource(someUser.namespace.toPath, _, 
None) }
+    val resources = collections map { Resource(someUser.namespace.name.toPath, 
_, None) }
 
     resources foreach { r =>
       Await.ready(entitlementProvider.check(someUser, READ, r), 
requestTimeout).eitherValue.get shouldBe Right({})
@@ -78,9 +78,9 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
     val collections = Seq(ACTIONS, RULES, TRIGGERS, PACKAGES, ACTIVATIONS, 
NAMESPACES)
     val resources = collections map { c: Collection =>
       c match {
-        case RULES      => Resource(anotherUser.namespace.toPath, c, None)
-        case NAMESPACES => Resource(anotherUser.namespace.toPath, c, None)
-        case _          => Resource(someUser.namespace.toPath, c, None)
+        case RULES      => Resource(anotherUser.namespace.name.toPath, c, None)
+        case NAMESPACES => Resource(anotherUser.namespace.name.toPath, c, None)
+        case _          => Resource(someUser.namespace.name.toPath, c, None)
       }
     }
 
@@ -92,8 +92,8 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
     resourcesSet.map(r => resourcesList += r)
     val resourceNames = resourcesList.map(r => 
r.fqname).sorted.toSet.mkString(", ")
     val resourceOtherNames = Seq(
-      Resource(anotherUser.namespace.toPath, RULES, None),
-      Resource(anotherUser.namespace.toPath, NAMESPACES, None)).map(r => 
r.fqname).toSet.mkString(", ")
+      Resource(anotherUser.namespace.name.toPath, RULES, None),
+      Resource(anotherUser.namespace.name.toPath, NAMESPACES, None)).map(r => 
r.fqname).toSet.mkString(", ")
 
     Await.ready(entitlementProvider.check(someUser, READ, resourcesSet), 
requestTimeout).eitherValue.get shouldBe Left(
       RejectRequest(Forbidden, 
Messages.notAuthorizedtoAccessResource(resourceOtherNames)))
@@ -116,7 +116,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
   it should "not authorize a user to list someone else's collection or access 
it by other other right" in {
     implicit val tid = transid()
     val collections = Seq(ACTIONS, RULES, TRIGGERS, PACKAGES, ACTIVATIONS, 
NAMESPACES)
-    val resources = collections map { Resource(someUser.namespace.toPath, _, 
None) }
+    val resources = collections map { Resource(someUser.namespace.name.toPath, 
_, None) }
     resources foreach { r =>
       // it is permissible to list packages in any namespace (provided they 
are either owned by
       // the subject requesting access or the packages are public); that is, 
the entitlement is more
@@ -143,7 +143,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
     implicit val tid = transid()
     // packages are tested separately
     val collections = Seq(ACTIONS, RULES, TRIGGERS)
-    val resources = collections map { Resource(someUser.namespace.toPath, _, 
Some("xyz")) }
+    val resources = collections map { Resource(someUser.namespace.name.toPath, 
_, Some("xyz")) }
     resources foreach { r =>
       Await.ready(entitlementProvider.check(someUser, READ, r), 
requestTimeout).eitherValue.get shouldBe Right({})
       Await.ready(entitlementProvider.check(someUser, PUT, r), 
requestTimeout).eitherValue.get shouldBe Right({})
@@ -155,9 +155,11 @@ class EntitlementProviderTests extends 
ControllerTestCommon with ScalaFutures {
   it should "not authorize a user to CRUD an entity in a collection if authkey 
has no CRUD rights" in {
     implicit val tid = transid()
     val subject = Subject()
-    val someUser = Identity(subject, EntityName(subject.asString), AuthKey(), 
Set(Privilege.ACTIVATE))
+    val uuid = UUID()
+    val someUser =
+      Identity(subject, Namespace(EntityName(subject.asString), uuid), 
AuthKey(uuid, Secret()), Set(Privilege.ACTIVATE))
     val collections = Seq(ACTIONS, RULES, TRIGGERS)
-    val resources = collections map { Resource(someUser.namespace.toPath, _, 
Some("xyz")) }
+    val resources = collections map { Resource(someUser.namespace.name.toPath, 
_, Some("xyz")) }
     resources foreach { r =>
       Await.ready(entitlementProvider.check(someUser, READ, r), 
requestTimeout).eitherValue.get shouldBe Left(
         RejectRequest(Forbidden, 
Messages.notAuthorizedtoAccessResource(r.fqname)))
@@ -172,7 +174,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
   it should "not authorize a user to CRUD or activate an entity in a 
collection that does not support CRUD or activate" in {
     implicit val tid = transid()
     val collections = Seq(NAMESPACES, ACTIVATIONS)
-    val resources = collections map { Resource(someUser.namespace.toPath, _, 
Some("xyz")) }
+    val resources = collections map { Resource(someUser.namespace.name.toPath, 
_, Some("xyz")) }
     resources foreach { r =>
       Await.ready(entitlementProvider.check(someUser, READ, r), 
requestTimeout).eitherValue.get shouldBe Right({})
       Await.ready(entitlementProvider.check(someUser, PUT, r), 
requestTimeout).eitherValue.get shouldBe Left(
@@ -187,7 +189,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
   it should "not authorize a user to CRUD or activate an entity in someone 
else's collection" in {
     implicit val tid = transid()
     val collections = Seq(ACTIONS, RULES, TRIGGERS, PACKAGES)
-    val resources = collections map { Resource(someUser.namespace.toPath, _, 
Some("xyz")) }
+    val resources = collections map { Resource(someUser.namespace.name.toPath, 
_, Some("xyz")) }
     resources foreach { r =>
       Await.ready(entitlementProvider.check(guestUser, READ, r), 
requestTimeout).eitherValue.get shouldBe Left(
         RejectRequest(Forbidden, 
Messages.notAuthorizedtoAccessResource(r.fqname)))
@@ -203,7 +205,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
   it should "authorize a user to list, create/update/delete a package" in {
     implicit val tid = transid()
     val collections = Seq(PACKAGES)
-    val resources = collections map { Resource(someUser.namespace.toPath, _, 
Some("xyz")) }
+    val resources = collections map { Resource(someUser.namespace.name.toPath, 
_, Some("xyz")) }
     resources foreach { r =>
       // read should fail because the lookup for the package will fail
       Await.ready(entitlementProvider.check(someUser, READ, r), 
requestTimeout).eitherValue.get shouldBe Left(
@@ -219,8 +221,8 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
 
   it should "grant access to entire collection to another user" in {
     implicit val tid = transid()
-    val all = Resource(someUser.namespace.toPath, ACTIONS, None)
-    val one = Resource(someUser.namespace.toPath, ACTIONS, Some("xyz"))
+    val all = Resource(someUser.namespace.name.toPath, ACTIONS, None)
+    val one = Resource(someUser.namespace.name.toPath, ACTIONS, Some("xyz"))
     Await.ready(entitlementProvider.check(adminUser, READ, all), 
requestTimeout).eitherValue.get should not be Right({})
     Await.ready(entitlementProvider.check(adminUser, READ, one), 
requestTimeout).eitherValue.get should not be Right({})
     Await.result(entitlementProvider.grant(adminUser.subject, READ, all), 
requestTimeout) // granted
@@ -231,8 +233,8 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
 
   it should "grant access to specific resource to a user" in {
     implicit val tid = transid()
-    val all = Resource(someUser.namespace.toPath, ACTIONS, None)
-    val one = Resource(someUser.namespace.toPath, ACTIONS, Some("xyz"))
+    val all = Resource(someUser.namespace.name.toPath, ACTIONS, None)
+    val one = Resource(someUser.namespace.name.toPath, ACTIONS, Some("xyz"))
     Await.ready(entitlementProvider.check(adminUser, READ, all), 
requestTimeout).eitherValue.get should not be Right({})
     Await.ready(entitlementProvider.check(adminUser, READ, one), 
requestTimeout).eitherValue.get should not be Right({})
     Await
@@ -271,11 +273,11 @@ class EntitlementProviderTests extends 
ControllerTestCommon with ScalaFutures {
       case (priv, who, expected) =>
         val check = new PackageCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
           // any user can list any namespace packages
           // (because this performs a db view lookup which is later filtered)
-          Resource(someUser.namespace.toPath, PACKAGES, None))
+          Resource(someUser.namespace.name.toPath, PACKAGES, None))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
     }
   }
@@ -300,9 +302,9 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       case (priv, who, expected) =>
         val check = new PackageCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
-          Resource(someUser.namespace.toPath, PACKAGES, Some("xyz")))
+          Resource(someUser.namespace.name.toPath, PACKAGES, Some("xyz")))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
     }
   }
@@ -324,15 +326,15 @@ class EntitlementProviderTests extends 
ControllerTestCommon with ScalaFutures {
       (REJECT, guestUser, Right(false)))
 
     // this forces a doc mismatch error
-    val action = WhiskAction(someUser.namespace.toPath, MakeName.next(), 
jsDefault(""))
+    val action = WhiskAction(someUser.namespace.name.toPath, MakeName.next(), 
jsDefault(""))
     put(entityStore, action)
     paths foreach {
       case (priv, who, expected) =>
         val check = new PackageCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
-          Resource(someUser.namespace.toPath, PACKAGES, 
Some(action.name.asString)))
+          Resource(someUser.namespace.name.toPath, PACKAGES, 
Some(action.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
     }
   }
@@ -341,7 +343,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
     implicit val tid = transid()
     implicit val ep = entitlementProvider
 
-    val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next())
+    val provider = WhiskPackage(someUser.namespace.name.toPath, 
MakeName.next())
     put(entityStore, provider)
 
     val paths = Seq(
@@ -360,9 +362,9 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       case (priv, who, expected) =>
         val check = new PackageCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
-          Resource(someUser.namespace.toPath, PACKAGES, 
Some(provider.name.asString)))
+          Resource(someUser.namespace.name.toPath, PACKAGES, 
Some(provider.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
     }
   }
@@ -372,8 +374,8 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
     implicit val ep = entitlementProvider
 
     // simulate entitlement change on package for which binding was once 
entitled
-    val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next())
-    val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), 
provider.bind)
+    val provider = WhiskPackage(someUser.namespace.name.toPath, 
MakeName.next())
+    val binding = WhiskPackage(guestUser.namespace.name.toPath, 
MakeName.next(), provider.bind)
     put(entityStore, provider, false)
     put(entityStore, binding)
 
@@ -393,9 +395,9 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       case (priv, who, expected) =>
         val check = new PackageCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
-          Resource(guestUser.namespace.toPath, PACKAGES, 
Some(binding.name.asString)))
+          Resource(guestUser.namespace.name.toPath, PACKAGES, 
Some(binding.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
     }
 
@@ -405,9 +407,9 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       case (priv, who, expected) =>
         val check = new PackageCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
-          Resource(guestUser.namespace.toPath, PACKAGES, 
Some(binding.name.asString)))
+          Resource(guestUser.namespace.name.toPath, PACKAGES, 
Some(binding.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
     }
   }
@@ -417,8 +419,8 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
     implicit val ep = entitlementProvider
 
     // simulate entitlement change on package for which binding was once 
entitled
-    val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), 
None, publish = true)
-    val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), 
provider.bind, publish = true)
+    val provider = WhiskPackage(someUser.namespace.name.toPath, 
MakeName.next(), None, publish = true)
+    val binding = WhiskPackage(guestUser.namespace.name.toPath, 
MakeName.next(), provider.bind, publish = true)
     put(entityStore, provider)
     put(entityStore, binding)
 
@@ -438,9 +440,9 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       case (priv, who, expected) =>
         val check = new PackageCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
-          Resource(guestUser.namespace.toPath, PACKAGES, 
Some(binding.name.asString)))
+          Resource(guestUser.namespace.name.toPath, PACKAGES, 
Some(binding.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
     }
   }
@@ -449,8 +451,8 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
     implicit val tid = transid()
     implicit val ep = entitlementProvider
 
-    val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), 
None, publish = true)
-    val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), 
provider.bind)
+    val provider = WhiskPackage(someUser.namespace.name.toPath, 
MakeName.next(), None, publish = true)
+    val binding = WhiskPackage(guestUser.namespace.name.toPath, 
MakeName.next(), provider.bind)
     put(entityStore, provider)
     put(entityStore, binding)
 
@@ -470,9 +472,9 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       case (priv, who, expected) =>
         val check = new PackageCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
-          Resource(guestUser.namespace.toPath, PACKAGES, 
Some(binding.name.asString)))
+          Resource(guestUser.namespace.name.toPath, PACKAGES, 
Some(binding.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
     }
   }
@@ -499,11 +501,11 @@ class EntitlementProviderTests extends 
ControllerTestCommon with ScalaFutures {
       case (priv, who, expected) =>
         val check = new ActionCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
           // any user can list any namespace packages
           // (because this performs a db view lookup which is later filtered)
-          Resource(someUser.namespace.toPath, ACTIONS, None))
+          Resource(someUser.namespace.name.toPath, ACTIONS, None))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
     }
   }
@@ -524,7 +526,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       (ACTIVATE, guestUser, Right(true)),
       (REJECT, guestUser, Right(false)))
 
-    val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), 
None, publish = true)
+    val provider = WhiskPackage(someUser.namespace.name.toPath, 
MakeName.next(), None, publish = true)
     val action = WhiskAction(provider.fullPath, MakeName.next(), jsDefault(""))
     put(entityStore, provider)
     put(entityStore, action)
@@ -533,7 +535,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       case (priv, who, expected) =>
         val check = new ActionCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
           Resource(action.namespace, ACTIONS, Some(action.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
@@ -544,7 +546,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
     implicit val tid = transid()
     implicit val ep = entitlementProvider
 
-    val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), 
None, publish = false)
+    val provider = WhiskPackage(someUser.namespace.name.toPath, 
MakeName.next(), None, publish = false)
     val action = WhiskAction(provider.fullPath, MakeName.next(), jsDefault(""))
     put(entityStore, provider)
     put(entityStore, action)
@@ -567,7 +569,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       case (priv, who, expected) =>
         val check = new ActionCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
           Resource(action.namespace, ACTIONS, Some(action.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
@@ -578,8 +580,8 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
     implicit val tid = transid()
     implicit val ep = entitlementProvider
 
-    val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), 
None, publish = true)
-    val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), 
provider.bind)
+    val provider = WhiskPackage(someUser.namespace.name.toPath, 
MakeName.next(), None, publish = true)
+    val binding = WhiskPackage(guestUser.namespace.name.toPath, 
MakeName.next(), provider.bind)
     val action = WhiskAction(binding.fullPath, MakeName.next(), jsDefault(""))
     put(entityStore, provider)
     put(entityStore, binding)
@@ -603,7 +605,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       case (priv, who, expected) =>
         val check = new ActionCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
           Resource(action.namespace, ACTIONS, Some(action.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
@@ -614,8 +616,8 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
     implicit val tid = transid()
     implicit val ep = entitlementProvider
 
-    val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), 
None, publish = false)
-    val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), 
provider.bind)
+    val provider = WhiskPackage(someUser.namespace.name.toPath, 
MakeName.next(), None, publish = false)
+    val binding = WhiskPackage(guestUser.namespace.name.toPath, 
MakeName.next(), provider.bind)
     val action = WhiskAction(binding.fullPath, MakeName.next(), jsDefault(""))
     put(entityStore, provider)
     put(entityStore, binding)
@@ -639,7 +641,7 @@ class EntitlementProviderTests extends ControllerTestCommon 
with ScalaFutures {
       case (priv, who, expected) =>
         val check = new ActionCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
           Resource(action.namespace, ACTIONS, Some(action.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
@@ -662,14 +664,14 @@ class EntitlementProviderTests extends 
ControllerTestCommon with ScalaFutures {
       (ACTIVATE, guestUser, Right(false)),
       (REJECT, guestUser, Right(false)))
 
-    val action = WhiskAction(someUser.namespace.toPath, MakeName.next(), 
jsDefault(""))
+    val action = WhiskAction(someUser.namespace.name.toPath, MakeName.next(), 
jsDefault(""))
     put(entityStore, action)
 
     paths foreach {
       case (priv, who, expected) =>
         val check = new ActionCollection(entityStore).implicitRights(
           who,
-          Set(who.namespace.asString),
+          Set(who.namespace.name.asString),
           priv,
           Resource(action.namespace, ACTIONS, Some(action.name.asString)))
         Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
diff --git 
a/tests/src/test/scala/whisk/core/controller/test/PackagesApiTests.scala 
b/tests/src/test/scala/whisk/core/controller/test/PackagesApiTests.scala
index 9e48eed..890cee7 100644
--- a/tests/src/test/scala/whisk/core/controller/test/PackagesApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/PackagesApiTests.scala
@@ -264,7 +264,7 @@ class PackagesApiTests extends ControllerTestCommon with 
WhiskPackagesApi {
       waitOnView(entityStore, WhiskPackage, namespaces(0), 1)
       waitOnView(entityStore, WhiskPackage, namespaces(1), 1)
       waitOnView(entityStore, WhiskPackage, namespaces(2), 1)
-      val expected = providers filter (_.namespace == creds.namespace.toPath)
+      val expected = providers filter (_.namespace == 
creds.namespace.name.toPath)
 
       Get(s"$collectionPath?public=true") ~> Route.seal(routes(creds)) ~> 
check {
         status should be(OK)
diff --git 
a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala 
b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
index 7f8cde0..c54797b 100644
--- a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
@@ -121,9 +121,11 @@ class WebActionsApiTests extends FlatSpec with Matchers 
with WebActionsApiBaseTe
 }
 
 trait WebActionsApiBaseTests extends ControllerTestCommon with 
BeforeAndAfterEach with WhiskWebActionsApi {
+  val uuid = UUID()
   val systemId = Subject()
-  val systemKey = AuthKey()
-  val systemIdentity = Future.successful(Identity(systemId, 
EntityName(systemId.asString), systemKey, Privilege.ALL))
+  val systemKey = AuthKey(uuid, Secret())
+  val systemIdentity =
+    Future.successful(Identity(systemId, 
Namespace(EntityName(systemId.asString), uuid), systemKey, Privilege.ALL))
   override lazy val entitlementProvider = new 
TestingEntitlementProvider(whiskConfig, loadBalancer)
   protected val testRoutePath = webInvokePathSegments.mkString("/", "/", "")
 
@@ -404,7 +406,10 @@ trait WebActionsApiBaseTests extends ControllerTestCommon 
with BeforeAndAfterEac
                   "pkg" -> s"$systemId/proxy".toJson,
                   "action" -> "export_auth".toJson,
                   "content" -> metaPayload(m.method.name.toLowerCase, 
JsObject(), creds, pkgName = "proxy"))
-                
response.fields("content").asJsObject.fields(webApiDirectives.namespace) 
shouldBe user.namespace.toJson
+                response
+                  .fields("content")
+                  .asJsObject
+                  .fields(webApiDirectives.namespace) shouldBe 
user.namespace.name.toJson
               }
             } else {
               m(s"$testRoutePath/${path}.json") ~> Route.seal(routes(creds)) 
~> check {
@@ -429,7 +434,10 @@ trait WebActionsApiBaseTests extends ControllerTestCommon 
with BeforeAndAfterEac
                   creds,
                   pkgName = "proxy",
                   headers = List(RawHeader("X-Require-Whisk-Auth", 
requireAuthenticationKey))))
-              
response.fields("content").asJsObject.fields(webApiDirectives.namespace) 
shouldBe user.namespace.toJson
+              response
+                .fields("content")
+                .asJsObject
+                .fields(webApiDirectives.namespace) shouldBe 
user.namespace.name.toJson
             }
 
             // web action require-whisk-auth is set, but the header 
X-Require-Whisk-Auth value does not match
diff --git 
a/tests/src/test/scala/whisk/core/controller/test/WhiskAuthHelpers.scala 
b/tests/src/test/scala/whisk/core/controller/test/WhiskAuthHelpers.scala
index 1c356bf..7d21aee 100644
--- a/tests/src/test/scala/whisk/core/controller/test/WhiskAuthHelpers.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/WhiskAuthHelpers.scala
@@ -24,13 +24,14 @@ import whisk.core.entity.WhiskAuth
 import whisk.core.entity.Subject
 import whisk.core.entitlement.Privilege
 import whisk.core.entity.Identity
+import whisk.core.entity.Namespace
 
 object WhiskAuthHelpers {
   def newAuth(s: Subject = Subject(), k: AuthKey = AuthKey()) = {
-    WhiskAuth(s, Set(WhiskNamespace(EntityName(s.asString), k)))
+    WhiskAuth(s, Set(WhiskNamespace(Namespace(EntityName(s.asString), k.uuid), 
k)))
   }
 
   def newIdentity(s: Subject = Subject(), k: AuthKey = AuthKey()) = {
-    Identity(s, EntityName(s.asString), k, Privilege.ALL)
+    Identity(s, Namespace(EntityName(s.asString), k.uuid), k, Privilege.ALL)
   }
 }
diff --git 
a/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreBehaviorBase.scala
 
b/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreBehaviorBase.scala
index 239bbfc..96824ea 100644
--- 
a/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreBehaviorBase.scala
+++ 
b/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreBehaviorBase.scala
@@ -108,7 +108,8 @@ trait ArtifactStoreBehaviorBase
   }
 
   protected def wskNS(name: String) = {
-    WhiskNamespace(EntityName(name), AuthKey())
+    val uuid = UUID()
+    WhiskNamespace(Namespace(EntityName(name), uuid), AuthKey(uuid, Secret()))
   }
 
   private val exec = BlackBoxExec(ExecManifest.ImageName("image"), None, None, 
native = false)
diff --git 
a/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreSubjectQueryBehaviors.scala
 
b/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreSubjectQueryBehaviors.scala
index ce78397..ace1955 100644
--- 
a/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreSubjectQueryBehaviors.scala
+++ 
b/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreSubjectQueryBehaviors.scala
@@ -33,10 +33,12 @@ trait ArtifactStoreSubjectQueryBehaviors extends 
ArtifactStoreBehaviorBase {
 
   it should "find subject by namespace" in {
     implicit val tid: TransactionId = transid()
-    val ak1 = AuthKey()
-    val ak2 = AuthKey()
-    val ns1 = aname()
-    val ns2 = aname()
+    val uuid1 = UUID()
+    val uuid2 = UUID()
+    val ak1 = AuthKey(uuid1, Secret())
+    val ak2 = AuthKey(uuid2, Secret())
+    val ns1 = Namespace(aname(), uuid1)
+    val ns2 = Namespace(aname(), uuid2)
     val subs =
       Array(WhiskAuth(Subject(), Set(WhiskNamespace(ns1, ak1))), 
WhiskAuth(Subject(), Set(WhiskNamespace(ns2, ak2))))
     subs foreach (put(authStore, _))
@@ -44,7 +46,7 @@ trait ArtifactStoreSubjectQueryBehaviors extends 
ArtifactStoreBehaviorBase {
     waitOnView(authStore, ak1, 1)
     waitOnView(authStore, ak2, 1)
 
-    val s1 = Identity.get(authStore, ns1).futureValue
+    val s1 = Identity.get(authStore, ns1.name).futureValue
     s1.subject shouldBe subs(0).subject
 
     val s2 = Identity.get(authStore, ak2).futureValue
@@ -53,20 +55,23 @@ trait ArtifactStoreSubjectQueryBehaviors extends 
ArtifactStoreBehaviorBase {
 
   it should "not get blocked subject" in {
     implicit val tid: TransactionId = transid()
-    val ns1 = aname()
+    val uuid1 = UUID()
+    val ns1 = Namespace(aname(), uuid1)
     val ak1 = AuthKey()
     val auth = new ExtendedAuth(Subject(), Set(WhiskNamespace(ns1, ak1)), 
blocked = true)
     put(authStore, auth)
 
-    Identity.get(authStore, ns1).failed.futureValue shouldBe 
a[NoDocumentException]
+    Identity.get(authStore, ns1.name).failed.futureValue shouldBe 
a[NoDocumentException]
   }
 
   it should "not find subject when authKey matches partially" in {
     implicit val tid: TransactionId = transid()
-    val ak1 = AuthKey()
-    val ak2 = AuthKey()
-    val ns1 = aname()
-    val ns2 = aname()
+    val uuid1 = UUID()
+    val uuid2 = UUID()
+    val ak1 = AuthKey(uuid1, Secret())
+    val ak2 = AuthKey(uuid2, Secret())
+    val ns1 = Namespace(aname(), uuid1)
+    val ns2 = Namespace(aname(), uuid2)
 
     val auth = WhiskAuth(
       Subject(),
@@ -80,10 +85,12 @@ trait ArtifactStoreSubjectQueryBehaviors extends 
ArtifactStoreBehaviorBase {
 
   it should "find subject by namespace with limits" in {
     implicit val tid: TransactionId = transid()
-    val ak1 = AuthKey()
-    val ak2 = AuthKey()
-    val name1 = aname()
-    val name2 = aname()
+    val uuid1 = UUID()
+    val uuid2 = UUID()
+    val ak1 = AuthKey(uuid1, Secret())
+    val ak2 = AuthKey(uuid2, Secret())
+    val name1 = Namespace(aname(), uuid1)
+    val name2 = Namespace(aname(), uuid2)
     val subs = Array(
       WhiskAuth(Subject(), Set(WhiskNamespace(name1, ak1))),
       WhiskAuth(Subject(), Set(WhiskNamespace(name2, ak2))))
@@ -93,9 +100,9 @@ trait ArtifactStoreSubjectQueryBehaviors extends 
ArtifactStoreBehaviorBase {
     waitOnView(authStore, ak2, 1)
 
     val limits = UserLimits(invocationsPerMinute = Some(7), firesPerMinute = 
Some(31))
-    put(authStore, new LimitEntity(name1, limits))
+    put(authStore, new LimitEntity(name1.name, limits))
 
-    val i = Identity.get(authStore, name1).futureValue
+    val i = Identity.get(authStore, name1.name).futureValue
     i.subject shouldBe subs(0).subject
     i.limits shouldBe limits
   }
@@ -109,8 +116,10 @@ trait ArtifactStoreSubjectQueryBehaviors extends 
ArtifactStoreBehaviorBase {
     val n4 = aname()
     val n5 = aname()
 
-    val ak1 = AuthKey()
-    val ak2 = AuthKey()
+    val uuid1 = UUID()
+    val uuid2 = UUID()
+    val ak1 = AuthKey(uuid1, Secret())
+    val ak2 = AuthKey(uuid2, Secret())
 
     //Create 3 limits entry where one has limits > 0 thus non blacklisted
     //And one blocked subject with 2 namespaces
@@ -118,7 +127,10 @@ trait ArtifactStoreSubjectQueryBehaviors extends 
ArtifactStoreBehaviorBase {
       new LimitEntity(n1, UserLimits(invocationsPerMinute = Some(0))),
       new LimitEntity(n2, UserLimits(concurrentInvocations = Some(0))),
       new LimitEntity(n3, UserLimits(invocationsPerMinute = Some(7), 
concurrentInvocations = Some(7))),
-      new ExtendedAuth(Subject(), Set(WhiskNamespace(n4, ak1), 
WhiskNamespace(n5, ak2)), blocked = true))
+      new ExtendedAuth(
+        Subject(),
+        Set(WhiskNamespace(Namespace(n4, uuid1), ak1), 
WhiskNamespace(Namespace(n5, uuid2), ak2)),
+        blocked = true))
 
     limitsAndAuths foreach (put(authStore, _))
 
diff --git a/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala 
b/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala
index 6ee2b24..05e2f8d 100644
--- a/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala
+++ b/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala
@@ -187,6 +187,9 @@ class SchemaTests extends FlatSpec with BeforeAndAfter with 
ExecHelpers with Mat
     EntityPath.DEFAULT.resolveNamespace(EntityName("a")) shouldBe 
EntityPath("a")
     EntityPath("a").resolveNamespace(EntityName("b")) shouldBe EntityPath("a")
 
+    EntityPath.DEFAULT.resolveNamespace(Namespace(EntityName("a"), UUID())) 
shouldBe EntityPath("a")
+    EntityPath("a").resolveNamespace(Namespace(EntityName("b"), UUID())) 
shouldBe EntityPath("a")
+
     EntityPath("a").defaultPackage shouldBe true
     EntityPath("a/b").defaultPackage shouldBe false
 
diff --git 
a/tests/src/test/scala/whisk/core/invoker/test/NamespaceBlacklistTests.scala 
b/tests/src/test/scala/whisk/core/invoker/test/NamespaceBlacklistTests.scala
index e3bfd85..eb5f74d 100644
--- a/tests/src/test/scala/whisk/core/invoker/test/NamespaceBlacklistTests.scala
+++ b/tests/src/test/scala/whisk/core/invoker/test/NamespaceBlacklistTests.scala
@@ -62,32 +62,44 @@ class NamespaceBlacklistTests
     dbConfig.databaseFor[WhiskAuth])
 
   /* Identities needed for the first test */
+  val uuid1 = UUID()
+  val uuid2 = UUID()
+  val uuid3 = UUID()
   val identities = Seq(
-    Identity(Subject(), EntityName("testnamespace1"), AuthKey(), Set.empty, 
UserLimits(invocationsPerMinute = Some(0))),
     Identity(
       Subject(),
-      EntityName("testnamespace2"),
-      AuthKey(),
+      Namespace(EntityName("testnamespace1"), uuid1),
+      AuthKey(uuid1, Secret()),
+      Set.empty,
+      UserLimits(invocationsPerMinute = Some(0))),
+    Identity(
+      Subject(),
+      Namespace(EntityName("testnamespace2"), uuid2),
+      AuthKey(uuid2, Secret()),
       Set.empty,
       UserLimits(concurrentInvocations = Some(0))),
     Identity(
       Subject(),
-      EntityName("testnamespace3"),
-      AuthKey(),
+      Namespace(EntityName("testnamespace3"), uuid3),
+      AuthKey(uuid3, Secret()),
       Set.empty,
       UserLimits(invocationsPerMinute = Some(1), concurrentInvocations = 
Some(1))))
 
   /* Subject document needed for the second test */
-  val subject = WhiskAuth(
-    Subject(),
-    Set(WhiskNamespace(EntityName("different1"), AuthKey()), 
WhiskNamespace(EntityName("different2"), AuthKey())))
+  val uuid4 = UUID()
+  val uuid5 = UUID()
+  val ak4 = AuthKey(uuid4, Secret())
+  val ak5 = AuthKey(uuid5, Secret())
+  val ns4 = Namespace(EntityName("different1"), uuid4)
+  val ns5 = Namespace(EntityName("different2"), uuid5)
+  val subject = WhiskAuth(Subject(), Set(WhiskNamespace(ns4, ak4), 
WhiskNamespace(ns5, ak5)))
   val blockedSubject = JsObject(subject.toJson.fields + ("blocked" -> 
true.toJson))
 
   val blockedNamespacesCount = 2 + subject.namespaces.size
 
   def authToIdentities(auth: WhiskAuth): Set[Identity] = {
     auth.namespaces.map { ns =>
-      Identity(auth.subject, ns.name, ns.authkey, Set(), UserLimits())
+      Identity(auth.subject, ns.namespace, ns.authkey, Set(), UserLimits())
     }
   }
 
diff --git a/tests/src/test/scala/whisk/core/limits/ActionLimitsTests.scala 
b/tests/src/test/scala/whisk/core/limits/ActionLimitsTests.scala
index aa3caf8..77999fb 100644
--- a/tests/src/test/scala/whisk/core/limits/ActionLimitsTests.scala
+++ b/tests/src/test/scala/whisk/core/limits/ActionLimitsTests.scala
@@ -245,7 +245,7 @@ class ActionLimitsTests extends TestHelpers with 
WskTestHelpers {
     val allowedSize = ActivationEntityLimit.MAX_ACTIVATION_ENTITY_LIMIT.toBytes
 
     // Needs some bytes grace since activation message is not only the payload.
-    val args = Map("p" -> ("a" * (allowedSize - 700).toInt).toJson)
+    val args = Map("p" -> ("a" * (allowedSize - 750).toInt).toJson)
     val rr = wsk.action.invoke(name, args, blocking = true, expectedExitCode = 
TestUtils.SUCCESS_EXIT)
     val activation = 
wsk.parseJsonString(rr.respData).convertTo[ActivationResult]
 
diff --git 
a/tests/src/test/scala/whisk/core/loadBalancer/test/InvokerSupervisionTests.scala
 
b/tests/src/test/scala/whisk/core/loadBalancer/test/InvokerSupervisionTests.scala
index 6f0d05c..bf0da86 100644
--- 
a/tests/src/test/scala/whisk/core/loadBalancer/test/InvokerSupervisionTests.scala
+++ 
b/tests/src/test/scala/whisk/core/loadBalancer/test/InvokerSupervisionTests.scala
@@ -48,17 +48,7 @@ import whisk.core.WhiskConfig
 import whisk.core.connector.ActivationMessage
 import whisk.core.connector.PingMessage
 import whisk.core.entity.ActivationId.ActivationIdGenerator
-import whisk.core.entity.AuthKey
-import whisk.core.entity.DocRevision
-import whisk.core.entity.EntityName
-import whisk.core.entity.EntityPath
-import whisk.core.entity.ExecManifest
-import whisk.core.entity.FullyQualifiedEntityName
-import whisk.core.entity.Identity
-import whisk.core.entity.InstanceId
-import whisk.core.entity.Secret
-import whisk.core.entity.Subject
-import whisk.core.entity.UUID
+import whisk.core.entity._
 import whisk.core.loadBalancer.ActivationRequest
 import whisk.core.loadBalancer.GetStatus
 import whisk.core.loadBalancer.Healthy
@@ -189,14 +179,15 @@ class InvokerSupervisionTests
     val supervisor = system.actorOf(InvokerPool.props(childFactory, 
sendActivationToInvoker, pC))
 
     // Send ActivationMessage to InvokerPool
+    val uuid = UUID()
     val activationMessage = ActivationMessage(
       transid = TransactionId.invokerHealth,
       action = FullyQualifiedEntityName(EntityPath("whisk.system/utils"), 
EntityName("date")),
       revision = DocRevision.empty,
       user = Identity(
         Subject("unhealthyInvokerCheck"),
-        EntityName("unhealthyInvokerCheck"),
-        AuthKey(UUID(), Secret()),
+        Namespace(EntityName("unhealthyInvokerCheck"), uuid),
+        AuthKey(uuid, Secret()),
         Set[Privilege]()),
       activationId = new ActivationIdGenerator {}.make(),
       rootControllerIndex = InstanceId(0),

-- 
To stop receiving notification emails like this one, please contact
markusthoem...@apache.org.

Reply via email to