Security Model

Comprehensive overview of the Arya Banking security architecture: Keycloak, Vault, and JWT.

Security Architecture

Arya Banking implements a Zero Trust security model for microservices, centered around centralized identity management and secure secret orchestration.


1. Identity Management (Keycloak)

Keycloak serves as the primary Identity Provider (IdP) and Authorization Server.

Keycloak Realm: event-based-banking-application

The platform uses a dedicated realm to segregate banking users and services.

Core Clients

Client IDGrant TypeRole
banking-service-clientauthorization_codeBrowser/Mobile Login
auth-service-clientclient_credentialsAuth Service M2M
user-service-clientclient_credentialsUser Service M2M
admin-service-clientclient_credentialsAdmin Service (Keycloak API)
arya-banking-auth-clientpassword (ROPC)Direct internal authentication

RBAC Authorities

The standard realm_access.roles claim in the Keycloak JWT is extracted and converted into Spring Security authorities:

  • ADMINROLE_ADMIN
  • INTERNAL_SERVICEROLE_INTERNAL_SERVICE
  • USERROLE_USER

2. Secrets Management (HashiCorp Vault)

HashiCorp Vault is used to store sensitive configuration (database passwords, external API keys, etc.).

AppRole Authentication

Instead of static tokens, microservices use Vault AppRole to authenticate at startup.

  • Role ID: Unique ID for the service (configured per-service in .gitignore-d vault-credentials.yml).
  • Secret ID: A sensitive credential used to generate a temporary Vault token (same file).

Secret Paths

Secrets are organized by service and environment:

  • secret/data/arya-banking/user-service/dev
  • secret/data/arya-banking/auth-service/dev
  • secret/data/arya-banking/admin-service/dev

Configuration Flow


3. JWT Validation & Processing

The API Gateway and each Microservice operate as OAuth2 Resource Servers.

Validation Strategy

  1. Signature Verification: Services fetch the public keys (JWKs) from Keycloak's jwk-set-uri.
  2. Issuer Check: Validates that the token was issued by the trusted Keycloak realm.
  3. Expiry Check: Rejects expired tokens.

Common JWT Converter

Every service shares a consistent logic to extract roles from the realm_access claim:

Java code-highlight
// Found in SecurityConfig.java across services
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(jwt -> {
        Map<String, Object> realmAccess = jwt.getClaim("realm_access");
        Collection<String> roles = (Collection<String>) realmAccess.get("roles");
        return roles.stream()
            .map(role -> "ROLE_" + role)
            .map(SimpleGrantedAuthority::new)
            .collect(Collectors.toList());
    });
    return converter;
}

4. Security Observations & Hardening

Each service now externalizes Vault credentials via a gitignored vault-credentials.yml file. The bootstrap.yml contains only placeholder values that are overridden by the local file or environment variables.
AreaCurrent ImplementationRecommendation
PasswordsArgon2id (Keycloak)Keep as-is (industry standard).
SecretsVault AppRoleRotate Secret IDs frequently using a sidecar or Vault Agent.
Internal APIsROLE_INTERNAL_SERVICEImplement Mutual TLS (mTLS) for added transport-layer trust.
User APIspermitAll() in User ServiceNarrow scope to ROLE_USER or authenticated() after initial dev.