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 ID | Grant Type | Role |
|---|---|---|
banking-service-client | authorization_code | Browser/Mobile Login |
auth-service-client | client_credentials | Auth Service M2M |
user-service-client | client_credentials | User Service M2M |
admin-service-client | client_credentials | Admin Service (Keycloak API) |
arya-banking-auth-client | password (ROPC) | Direct internal authentication |
RBAC Authorities
The standard realm_access.roles claim in the Keycloak JWT is extracted and converted into Spring Security authorities:
ADMIN→ROLE_ADMININTERNAL_SERVICE→ROLE_INTERNAL_SERVICEUSER→ROLE_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-dvault-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/devsecret/data/arya-banking/auth-service/devsecret/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
- Signature Verification: Services fetch the public keys (JWKs) from Keycloak's
jwk-set-uri. - Issuer Check: Validates that the token was issued by the trusted Keycloak realm.
- Expiry Check: Rejects expired tokens.
Common JWT Converter
Every service shares a consistent logic to extract roles from the realm_access claim:
// 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
vault-credentials.yml file. The bootstrap.yml contains only placeholder values that are overridden by the local file or environment variables.| Area | Current Implementation | Recommendation |
|---|---|---|
| Passwords | Argon2id (Keycloak) | Keep as-is (industry standard). |
| Secrets | Vault AppRole | Rotate Secret IDs frequently using a sidecar or Vault Agent. |
| Internal APIs | ROLE_INTERNAL_SERVICE | Implement Mutual TLS (mTLS) for added transport-layer trust. |
| User APIs | permitAll() in User Service | Narrow scope to ROLE_USER or authenticated() after initial dev. |