SecureField Decryption & Permissions
Overview
- SecureField protects string fields at rest using AES-GCM and returns masked values to callers without explicit decryption privileges.
- Decryption is permission–gated by the ACL permission VIEW_DECRYPTED. Without this permission, getters return the literal token
<ENCRYPTED_VALUE/>
.
Key Rules
- Read vs. Decrypt: READ allows fetching the record, but not decrypting secured fields. VIEW_DECRYPTED is required to see plaintext.
- Anonymous: The anonymousUser can never decrypt. They may READ if allowed, but will always see
<ENCRYPTED_VALUE/>
. - System/Agents: SYSTEM and service agents may be granted VIEW_DECRYPTED as needed. Decryption only happens on the server.
- Writes: Without READ (and appropriate UPDATE/WRITE), clients cannot modify secure fields via standard endpoints.
Runtime Behavior
- The aspect
SecureFieldAspect
intercepts getters/setters for fields annotated with@SecureField
. - On get():
- If encryption type is HASHED → proceed (no decrypt attempt).
- Else check:
PermissionEvaluator.hasPermission(auth, target, 'VIEW_DECRYPTED')
.- True → decrypt and return plaintext.
- False/unknown → return
<ENCRYPTED_VALUE/>
without attempting decryption.
- On set():
- Encrypts clear text (or writes bcrypt for HASHED) before persisting.
Grant Patterns
- Grant READ to roles/users/anonymous for public visibility.
- Grant VIEW_DECRYPTED only to trusted SIDs:
- SYSTEM (internal services): to perform server-side operations needing keys.
- Specific Agents/Services: for controlled access to credentials.
- Never grant VIEW_DECRYPTED to anonymousUser.
UI Notes
- The PermissionDialog includes one-click helpers:
- “Grant SYSTEM decrypt” → adds VIEW_DECRYPTED for SYSTEM SID.
- “Grant ANONYMOUS read” → adds READ only; still masked.
Testing
- Unit test
SecureFieldPermissionMaskTest
ensures callers without a PermissionEvaluator (or without permission) receive the mask token. - Additional integration tests recommended:
- Anonymous READ → masked.
- Authenticated READ only → masked.
- Authenticated with VIEW_DECRYPTED → plaintext.
Changelog
- SecureFieldAspect now enforces VIEW_DECRYPTED before decrypting and masks otherwise.