feat: decrypt Jasypt values in .env and Spring files
CI / Checks (pull_request) Successful in 39s
PR title / Conventional title (pull_request) Successful in 1s

ENC(...) values are decrypted on reveal, copy or get with
jasypt-spring-boot's default algorithm (3.0+, PBEWITHHMACSHA512ANDAES_256).

- The password is, as in Spring, $JASYPT_ENCRYPTOR_PASSWORD, else the
  file's own jasypt.encryptor.password (JASYPT_ENCRYPTOR_PASSWORD in a
  .env), with ${VAR} and ${VAR:default} read from the environment.
- Errors say which password was used, or which one is missing.
- Secrets show a detail after their name: jasypt, or reference for a
  Spring ${VAR}; also in Go to and Favourites.
- A .env whose values are all Jasypt isn't marked as plain text in git.
This commit is contained in:
keb committed 2026-10-15 13:31:05 +02:00
1 parent 96395cb6a2
commit e1f86c72f7
13 files changed
+381 -29

No files matched your search

+7 -10
View File
@@ -15,6 +15,7 @@ import (
"go.yaml.in/yaml/v3"
"git.kebcloud.no/keb/lazysecrets/internal/jasypt"
"git.kebcloud.no/keb/lazysecrets/internal/provider"
)
@@ -137,7 +138,7 @@ func (k springKey) reference() bool {
}
func (k springKey) jasypt() bool {
return strings.HasPrefix(k.value, "ENC(") && strings.HasSuffix(k.value, ")")
return jasypt.Is(k.value)
}
// plain reports whether the file holds the value itself, readable.
@@ -346,15 +347,15 @@ func (p *Provider) springObjects(c provider.Container, b []byte) ([]provider.Obj
if !filter.secret(k) {
continue
}
state := provider.Attr{Label: "encrypted", Value: "no: plain text in the file"}
state, detail := provider.Attr{Label: "encrypted", Value: "no: plain text in the file"}, ""
switch {
case k.reference():
state = provider.Attr{Label: "value", Value: "a reference: the secret is set elsewhere"}
state, detail = provider.Attr{Label: "value", Value: "a reference: the secret is set elsewhere"}, "reference"
case k.jasypt():
state = provider.Attr{Label: "encrypted", Value: "jasypt"}
state, detail = provider.Attr{Label: "encrypted", Value: "jasypt"}, "jasypt"
}
out = append(out, provider.Object{
Container: c, Type: provider.TypeSecret, ID: c.ID + "\x00" + k.name, Name: k.name,
Container: c, Type: provider.TypeSecret, ID: c.ID + "\x00" + k.name, Name: k.name, Detail: detail,
Attrs: []provider.Attr{format, state},
})
}
@@ -403,12 +404,8 @@ func (p *Provider) springDetails(c provider.Container) (attrs []provider.Attr, p
jasypt++
}
}
encryption := "none: plain text"
if jasypt > 0 {
encryption = fmt.Sprintf("jasypt: %d of %d values", jasypt, len(keys))
}
return []provider.Attr{
{Label: "encryption", Value: encryption},
{Label: "encryption", Value: jasyptShare(jasypt, len(keys))},
{Label: "other keys", Value: fmt.Sprintf("%d, not matched by the secret patterns", len(keys)-secrets)},
}, plain
}