Class PatEncryptionService

java.lang.Object
edu.ucsb.cs.scaffold.services.PatEncryptionService

@Service public class PatEncryptionService extends Object
Encrypts and decrypts users' GitHub personal access tokens (PATs) with AES-256-GCM so the database only ever sees ciphertext.

Keys are supplied via environment variables in the form <version>:<base64 of 32 bytes>; see docs/PAT_ENCRYPTION_KEY_instructions.md. PAT_ENCRYPTION_KEY is the current key, used for all encryption. During a key rotation, PREVIOUS_PAT_ENCRYPTION_KEY additionally holds the key being retired, so credentials encrypted under it can still be decrypted until the rotate-keys job re-encrypts them under the current key.

When neither variable is set the service is "not configured": the app still boots (so deployments that don't use the PAT feature are unaffected), but encryption requests fail with IllegalStateException. A malformed key value, by contrast, fails at startup — a typo in key configuration should be loud, not silently treated as "feature off".

  • Constructor Details

    • PatEncryptionService

      public PatEncryptionService(@Value("${app.pat.encryption.key:}") String currentKey, @Value("${app.pat.encryption.previous-key:}") String previousKey)
  • Method Details

    • isConfigured

      public boolean isConfigured()
      Whether a current encryption key is configured.
    • currentKeyVersion

      public int currentKeyVersion()
      The key version new encryptions are performed under (the rotate-keys job's target).
    • encrypt

      public PatEncryptionService.EncryptedPat encrypt(String plaintext)
      Encrypts a PAT under the current key.
    • decrypt

      public String decrypt(String ciphertext, int keyVersion)
      Decrypts a stored PAT using the key that encrypted it, identified by the credential's stored key version.
      Throws:
      NoSuchKeyVersionException - if no key is configured for that version