Begun work to validate application identifier designator for tenant token as well.
diff --git a/api/src/main/java/io/mifos/anubis/api/v1/TokenConstants.java b/api/src/main/java/io/mifos/anubis/api/v1/TokenConstants.java
index e2b2eba..d8da9fe 100644
--- a/api/src/main/java/io/mifos/anubis/api/v1/TokenConstants.java
+++ b/api/src/main/java/io/mifos/anubis/api/v1/TokenConstants.java
@@ -26,6 +26,7 @@
   String JWT_SIGNATURE_TIMESTAMP_CLAIM = "/mifos.io/signatureTimestamp";
   String JWT_ENDPOINT_SET_CLAIM = "/mifos.io/endpointSet";
   String JWT_CONTENT_CLAIM = "/mifos.io/tokenContent";
+  String JWT_SOURCE_APPLICATION_CLAIM = "/mifos.io/sourceApplication";
 
   String REFRESH_TOKEN_COOKIE_NAME = "org.apache.fineract.refreshToken";
 }
diff --git a/library/src/main/java/io/mifos/anubis/security/AnubisAuthentication.java b/library/src/main/java/io/mifos/anubis/security/AnubisAuthentication.java
index ab7385f..65b3a7c 100644
--- a/library/src/main/java/io/mifos/anubis/security/AnubisAuthentication.java
+++ b/library/src/main/java/io/mifos/anubis/security/AnubisAuthentication.java
@@ -33,15 +33,20 @@
   private final String token;
   private final String userIdentifier;
   private final String forApplicationName;
+  private final String sourceApplicationName;
   private final Set<ApplicationPermission> applicationPermissions;
 
-  AnubisAuthentication(final String token, final String userIdentifier, final String forApplicationName,
-      final Set<ApplicationPermission> applicationPermissions) {
+  AnubisAuthentication(final String token,
+                       final String userIdentifier,
+                       final String forApplicationName,
+                       final String sourceApplicationName,
+                       final Set<ApplicationPermission> applicationPermissions) {
     authenticated = true;
 
     this.token = token;
     this.userIdentifier = userIdentifier;
     this.forApplicationName = forApplicationName;
+    this.sourceApplicationName = sourceApplicationName;
     this.applicationPermissions = Collections.unmodifiableSet(new HashSet<>(applicationPermissions));
   }
 
@@ -62,7 +67,7 @@
 
   @Override
   public AnubisPrincipal getPrincipal() {
-    return new AnubisPrincipal(userIdentifier, forApplicationName);
+    return new AnubisPrincipal(userIdentifier, forApplicationName, sourceApplicationName);
   }
 
   @Override
diff --git a/library/src/main/java/io/mifos/anubis/security/AnubisPrincipal.java b/library/src/main/java/io/mifos/anubis/security/AnubisPrincipal.java
index 5b2a9bd..f0c0da2 100644
--- a/library/src/main/java/io/mifos/anubis/security/AnubisPrincipal.java
+++ b/library/src/main/java/io/mifos/anubis/security/AnubisPrincipal.java
@@ -24,10 +24,12 @@
 public class AnubisPrincipal {
   private final String user;
   private final String forApplicationName;
+  private final String sourceApplicationName;
 
-  AnubisPrincipal(String user, String forApplicationName) {
+  AnubisPrincipal(String user, String forApplicationName, String sourceApplicationName) {
     this.user = user;
     this.forApplicationName = forApplicationName;
+    this.sourceApplicationName = sourceApplicationName;
   }
 
   public String getUser() {
@@ -38,6 +40,10 @@
     return forApplicationName;
   }
 
+  public String getSourceApplicationName() {
+    return sourceApplicationName;
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) return true;
diff --git a/library/src/main/java/io/mifos/anubis/security/GuestAuthenticator.java b/library/src/main/java/io/mifos/anubis/security/GuestAuthenticator.java
index 12b2ce4..3a2e00e 100644
--- a/library/src/main/java/io/mifos/anubis/security/GuestAuthenticator.java
+++ b/library/src/main/java/io/mifos/anubis/security/GuestAuthenticator.java
@@ -52,6 +52,11 @@
 
     logger.info("Guest access \"authenticated\" successfully.", user);
 
-    return new AnubisAuthentication(null, RoleConstants.GUEST_USER_IDENTIFIER, applicationName.toString(), permissions);
+    return new AnubisAuthentication(
+            null,
+            RoleConstants.GUEST_USER_IDENTIFIER,
+            applicationName.toString(),
+            applicationName.toString(),
+            permissions);
   }
 }
diff --git a/library/src/main/java/io/mifos/anubis/security/SystemAuthenticator.java b/library/src/main/java/io/mifos/anubis/security/SystemAuthenticator.java
index 46c01e3..70ec3e7 100644
--- a/library/src/main/java/io/mifos/anubis/security/SystemAuthenticator.java
+++ b/library/src/main/java/io/mifos/anubis/security/SystemAuthenticator.java
@@ -78,7 +78,12 @@
 
       logger.info("System token for user {}, with key timestamp {} authenticated successfully.", user, keyTimestamp);
 
-      return new AnubisAuthentication(TokenConstants.PREFIX + token, user, result.getBody().getAudience(), permissions);
+      return new AnubisAuthentication(
+              TokenConstants.PREFIX + token,
+              user,
+              result.getBody().getAudience(),
+              TokenType.SYSTEM.getIssuer(),
+              permissions);
     }
     catch (final JwtException e) {
       logger.debug("token = {}", token);
diff --git a/library/src/main/java/io/mifos/anubis/security/TenantAuthenticator.java b/library/src/main/java/io/mifos/anubis/security/TenantAuthenticator.java
index bd53f33..b575de0 100644
--- a/library/src/main/java/io/mifos/anubis/security/TenantAuthenticator.java
+++ b/library/src/main/java/io/mifos/anubis/security/TenantAuthenticator.java
@@ -78,6 +78,7 @@
       @SuppressWarnings("unchecked") Jwt<Header, Claims> jwt = parser.parse(token);
 
       final String serializedTokenContent = jwt.getBody().get(TokenConstants.JWT_CONTENT_CLAIM, String.class);
+      final String sourceApplication = jwt.getBody().get(TokenConstants.JWT_SOURCE_APPLICATION_CLAIM, String.class);
       final TokenContent tokenContent = gson.fromJson(serializedTokenContent, TokenContent.class);
       if (tokenContent == null)
         throw AmitAuthenticationException.missingTokenContent();
@@ -88,7 +89,7 @@
       logger.info("Tenant token for user {}, with key timestamp {} authenticated successfully.", user, keyTimestamp);
 
       return new AnubisAuthentication(TokenConstants.PREFIX + token,
-          jwt.getBody().getSubject(), applicationNameWithVersion, permissions
+          jwt.getBody().getSubject(), applicationNameWithVersion, sourceApplication, permissions
       );
     }
     catch (final JwtException e) {
diff --git a/library/src/main/java/io/mifos/anubis/service/PermissionSegmentMatcher.java b/library/src/main/java/io/mifos/anubis/service/PermissionSegmentMatcher.java
index 1d856e4..84dbacb 100644
--- a/library/src/main/java/io/mifos/anubis/service/PermissionSegmentMatcher.java
+++ b/library/src/main/java/io/mifos/anubis/service/PermissionSegmentMatcher.java
@@ -59,8 +59,10 @@
       return true;
     else if (isUserIdentifierSegment())
       return requestSegment.equals(principal.getUser());
-    else if (isApplicationIdentifierSegment() && acceptTokenIntendedForForeignApplication)
+    else if (acceptTokenIntendedForForeignApplication && isApplicationIdentifierSegment())
       return requestSegment.equals(principal.getForApplicationName());
+    else if (!acceptTokenIntendedForForeignApplication && isApplicationIdentifierSegment())
+      return requestSegment.equals(principal.getSourceApplicationName());
     else if (isParameterSegment())
       return isSu;
     else
diff --git a/library/src/main/java/io/mifos/anubis/token/TenantAccessTokenSerializer.java b/library/src/main/java/io/mifos/anubis/token/TenantAccessTokenSerializer.java
index 29805f9..afdcc18 100644
--- a/library/src/main/java/io/mifos/anubis/token/TenantAccessTokenSerializer.java
+++ b/library/src/main/java/io/mifos/anubis/token/TenantAccessTokenSerializer.java
@@ -50,6 +50,7 @@
     private String user;
     private TokenContent tokenContent;
     private long secondsToLive;
+    private String sourceApplication;
 
     public Specification setKeyTimestamp(final String keyTimestamp) {
       this.keyTimestamp = keyTimestamp;
@@ -66,6 +67,11 @@
       return this;
     }
 
+    public Specification setSourceApplication(final String applicationIdentifier) {
+      this.sourceApplication = applicationIdentifier;
+      return this;
+    }
+
     public Specification setTokenContent(final TokenContent tokenContent) {
       this.tokenContent = tokenContent;
       return this;
@@ -89,12 +95,16 @@
     if (specification.privateKey == null) {
       throw new IllegalArgumentException("token signature privateKey must not be null.");
     }
+    if (specification.sourceApplication == null) {
+      throw new IllegalArgumentException("token signature source application must not be null.");
+    }
 
     final JwtBuilder jwtBuilder =
         Jwts.builder()
             .setSubject(specification.user)
             .claim(TokenConstants.JWT_SIGNATURE_TIMESTAMP_CLAIM, specification.keyTimestamp)
             .claim(TokenConstants.JWT_CONTENT_CLAIM, serializedTokenContent)
+            .claim(TokenConstants.JWT_SOURCE_APPLICATION_CLAIM, specification.sourceApplication)
             .setIssuer(TokenType.TENANT.getIssuer())
             .setIssuedAt(new Date(issued))
             .signWith(SignatureAlgorithm.RS512, specification.privateKey);
diff --git a/library/src/test/java/io/mifos/anubis/security/ApplicationPermissionTest.java b/library/src/test/java/io/mifos/anubis/security/ApplicationPermissionTest.java
index 8780f92..0061b7b 100644
--- a/library/src/test/java/io/mifos/anubis/security/ApplicationPermissionTest.java
+++ b/library/src/test/java/io/mifos/anubis/security/ApplicationPermissionTest.java
@@ -47,6 +47,7 @@
     private String requestedOperation = "GET";
     private String user = "Nebamun";
     private String forApplication = "graincounter-v1";
+    private String sourceApplication = "identity-v1";
     private boolean expectedResult = true;
 
     private TestCase(final String caseName) {
@@ -110,7 +111,7 @@
     }
 
     AnubisPrincipal getPrincipal() {
-      return new AnubisPrincipal(user, forApplication);
+      return new AnubisPrincipal(user, forApplication, sourceApplication);
     }
 
     TestCase user(final String newVal)
@@ -125,6 +126,12 @@
       return this;
     }
 
+    TestCase sourceApplication(final String newVal)
+    {
+      this.sourceApplication = newVal;
+      return this;
+    }
+
     boolean getExpectedResult() {
       return expectedResult;
     }
@@ -222,6 +229,33 @@
             .allowedOperation(AllowedOperation.CHANGE)
             .requestedOperation("PUT")
             .expectedResult(true));
+    ret.add(new TestCase("access token acquired from application refresh token accessing its own resource.")
+            .permittedPath("/applications/{applicationidentifier}/permissions")
+            .requestedPath("/applications/bop-v1/permissions")
+            .acceptTokenIntendedForForeignApplication(false)
+            .calledApplication("identity-v1").forApplication("identity-v1")
+            .sourceApplication("bop-v1")
+            .allowedOperation(AllowedOperation.CHANGE)
+            .requestedOperation("POST")
+            .expectedResult(true));
+    ret.add(new TestCase("access token acquired from application refresh token accessing another apps resource.")
+            .permittedPath("/applications/{applicationidentifier}/permissions")
+            .requestedPath("/applications/bop-v1/permissions")
+            .acceptTokenIntendedForForeignApplication(false)
+            .calledApplication("identity-v1").forApplication("identity-v1")
+            .sourceApplication("bee-v1")
+            .allowedOperation(AllowedOperation.CHANGE)
+            .requestedOperation("POST")
+            .expectedResult(false));
+    ret.add(new TestCase("access token acquired from application refresh token accessing sub resource not allowed.")
+            .permittedPath("/applications/{applicationidentifier}/permissions")
+            .requestedPath("/applications/bop-v1/permissions/identity__v1__roles/users/Nebamun/enabled")
+            .acceptTokenIntendedForForeignApplication(false)
+            .calledApplication("identity-v1").forApplication("identity-v1")
+            .sourceApplication("bop-v1")
+            .allowedOperation(AllowedOperation.CHANGE)
+            .requestedOperation("PUT")
+            .expectedResult(false));
 
     return ret;
   }
diff --git a/library/src/test/java/io/mifos/anubis/token/TenantAccessTokenSerializerTest.java b/library/src/test/java/io/mifos/anubis/token/TenantAccessTokenSerializerTest.java
index cd396a7..ef050ef 100644
--- a/library/src/test/java/io/mifos/anubis/token/TenantAccessTokenSerializerTest.java
+++ b/library/src/test/java/io/mifos/anubis/token/TenantAccessTokenSerializerTest.java
@@ -57,6 +57,7 @@
         = new TenantAccessTokenSerializer.Specification()
             .setKeyTimestamp("1234567")
         .setUser(USER)
+        .setSourceApplication("doo-v1")
         .setTokenContent(EXAMPLE_TOKEN_CONTENT)
         .setPrivateKey(keyPairHolder.privateKey())
         .setSecondsToLive(SECONDS_TO_LIVE);
@@ -95,6 +96,7 @@
     final TenantAccessTokenSerializer.Specification specification
         = new TenantAccessTokenSerializer.Specification()
         .setUser(USER)
+        .setSourceApplication("doo-v1")
         .setTokenContent(EXAMPLE_TOKEN_CONTENT)
         .setPrivateKey(keyPairHolder.privateKey())
         .setSecondsToLive(0);
diff --git a/test/src/main/java/io/mifos/anubis/test/v1/SystemSecurityEnvironment.java b/test/src/main/java/io/mifos/anubis/test/v1/SystemSecurityEnvironment.java
index faed373..4e00dd9 100644
--- a/test/src/main/java/io/mifos/anubis/test/v1/SystemSecurityEnvironment.java
+++ b/test/src/main/java/io/mifos/anubis/test/v1/SystemSecurityEnvironment.java
@@ -109,6 +109,7 @@
   {
     return tenantAccessTokenSerializer.build(new TenantAccessTokenSerializer.Specification()
             .setUser(userName)
+            .setSourceApplication("test-v1")
             .setTokenContent(getTokenContentForStarEndpoint(applicationNames))
             .setSecondsToLive(TimeUnit.HOURS.toSeconds(10))
             .setKeyTimestamp(tenantKeyTimestamp())
@@ -124,6 +125,7 @@
             new TenantAccessTokenSerializer.Specification().setPrivateKey(tenantPrivateKey())
                     .setKeyTimestamp(tenantKeyTimestamp())
                     .setSecondsToLive(100)
+                    .setSourceApplication("test-v1")
                     .setUser(userName)
                     .setTokenContent(generateOnePermissionTokenContent(applicationName, uri, allowedOperation))
     ).getToken();