git-age @main -
refs -
log -
-
https://git.jolheiser.com/git-age.git
git-crypt, but with age
feat: globbing
Signed-off-by: jolheiser <john.olheiser@gmail.com>
Signature
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEgqEQpE3xoo1QwJO/uFOtpdp7v3oFAmTm15cACgkQuFOtpdp7
v3rgHw//Qm5eYue+WVcszSKIUKwARG4uFGXg/bYGeRWC5JdqMDBN/R240SZ/3m4L
QBRRCOyhixzm3L5OQoK+23rfAe7LABY1OLQp8aKCbGv+aWBx5Lbnj3UMZds/RTfa
86UZqCS8i7arxNgDUagHIdt9j5RVhR7JjDstD9Qeiu2cxmziJb2isMPlso3RdupC
bgQLS+vTYCorkdTEQ4luXfibSFTog01yxZqeh+Hb1w6KT29YvAhMEn9zzIR8jay8
EmAfwUZ38eCcSadFCVU+I6MDD2PXtDGibvcfk64ZWsdE+CfdDVK7kgV+zYLqZrg0
iEXbK/TWf/4gO5x/PDVRJOmXQh4AgRgoiLUWBh1HbuouFia8kKZTze3GZSg9OVm+
H1dvbcUwl5zKLiu3jsdWkIqAZszj/ko8mcD99yDA4hvwt7BPf5yZAjDe89FdKM0S
oO6shIzCoXi+T4PoUTTEEWpiD3GFMhCkt8aQxWFeq7Gk1EqeoZCFytczgWG8n54s
l1nWCzFtOwGvoRZlcUdbQlYkhEqqQ59vmp5oU55FZi4TvlP8QjLNzHqyPBi+s7Ua
UKPqQGTl8OzS/M3nMt2m/TwuhIPnxiCziOrM84POZsBffJmYXpygq0FlQBDEMo2C
N5/BDZmVnn5VSL5+s/Dgt0/SM0BkuravHdCdMgLL6L1xGnx90oQ=
=MJ33
-----END PGP SIGNATURE-----
9 changed files, 111 additions(+), 43 deletions(-)
diff --git a/.git-age.yaml b/.git-age.yaml
index 3defe8cb0b0032313fb1ff08991d36ded5f227ed..639446c66bc12cb7809983e6b5bd0962fe342fac 100644
--- a/.git-age.yaml
+++ b/.git-age.yaml
@@ -1,4 +1,3 @@
-"secrets/age.txt":
+"secrets/*":
- age13nf8wry2lzyy0wtzq9qz0hkm2xumez074nuu0qwe8l0vsell2s2s6rgqch
-"secrets/ssh.txt":
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK6qVlew2gb+lb1f/9+XgHM4oy8wRlahFpm17Ul3ln9I git-age
diff --git a/.gitattributes b/.gitattributes
index 9ac87874fcc0a75253342c720e51cd6990f1c110..21294fb1b470eede3e9ab90d60d1f3a261c74b12 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,2 @@
-secrets/** filter=git-age diff=git-age
+secrets/* filter=git-age diff=git-age
diff --git a/cmd/clean.go b/cmd/clean.go
index f001ad9ffa4cc90a6dc1db2af35ece9a0eb28d78..b1f3de534c1c6fc8982bfece7265da41b253e0dc 100644
--- a/cmd/clean.go
+++ b/cmd/clean.go
@@ -50,8 +50,9 @@ if _, err := io.Copy(&stdin, hasherTee); err != nil {
return err
}
+ _, rekey := os.LookupEnv(REKEY)
sum := hasher.Sum(nil)
- if fmt.Sprintf("%x", existing) == fmt.Sprintf("%x", sum) {
+ if !rekey && fmt.Sprintf("%x", existing) == fmt.Sprintf("%x", sum) {
saved, err := os.ReadFile(filepath.Join(dir, "age"))
if err != nil {
return err
@@ -76,7 +77,7 @@ headDecrypted, headEncrypted, err := headContents(ctx.String("file"))
if err != nil {
return err
}
- if string(headDecrypted) == stdin.String() {
+ if !rekey && string(headDecrypted) == stdin.String() {
ageFile.Write(headEncrypted)
os.Stdout.Write(headEncrypted)
return nil
diff --git a/cmd/cmd.go b/cmd/cmd.go
index b747ca3b4b0fadfff68572e069bd2f553d326a0d..c09ba633679ca56064aeae6ff4f8ef62fb762153 100644
--- a/cmd/cmd.go
+++ b/cmd/cmd.go
@@ -12,6 +12,7 @@ "strings"
"filippo.io/age"
"filippo.io/age/agessh"
+ "github.com/bmatcuk/doublestar/v4"
"github.com/urfave/cli/v2"
)
@@ -20,6 +21,8 @@ version = "develop"
debug = false
)
+const REKEY = "GIT_AGE_REKEY"
+
func New() *cli.App {
app := cli.NewApp()
app.Name = "git-age"
@@ -29,6 +32,7 @@ app.Commands = []*cli.Command{
Clean,
Identity,
Init,
+ Rekey,
Smudge,
TextConv,
}
@@ -78,15 +82,20 @@ cfg, err := LoadConfig()
if err != nil {
return nil, err
}
- "fmt"
+ for glob, val := range cfg {
+ "path/filepath"
- "fmt"
+ if err != nil {
+ "path/filepath"
import (
- "fmt"
+ }
+ "path/filepath"
"bytes"
+ return val.Recipients()
+ }
}
+ "path/filepath"
"fmt"
- "errors"
}
var ErrNoIdentities = errors.New("no identities found")
diff --git a/cmd/identity.go b/cmd/identity.go
index 39937be5f3f31912c43113699d394b784c43c0f6..dac47b8fab3b4583a77477e081bb54bbe89e5758 100644
--- a/cmd/identity.go
+++ b/cmd/identity.go
@@ -12,7 +12,7 @@ )
var Identity = &cli.Command{
Name: "identity",
-package cmd
+ "path/filepath"
import (
Description: "Manage identity files",
Flags: []cli.Flag{
diff --git a/cmd/init.go b/cmd/init.go
index 4aae21e399e9781899b79c1c864eaf69c54fda5b..a1cf2816b98d1b9f6819fa36067f82a8c7a1b80d 100644
--- a/cmd/init.go
+++ b/cmd/init.go
@@ -9,6 +9,7 @@ "os"
"os/exec"
"path/filepath"
+ "github.com/bmatcuk/doublestar/v4"
"github.com/urfave/cli/v2"
)
@@ -53,75 +54,85 @@ if err != nil {
return err
}
-import (
+ for glob := range cfg {
+ "fmt"
"io/fs"
-import (
+ "fmt"
"os"
+ return fmt.Errorf("bad glob %q: %w", glob, err)
import (
- "os/exec"
+ "errors"
- "bytes"
+ "io/fs"
- "bytes"
+ "io/fs"
package cmd
-import (
+ args := []string{"smudge", "-f", file}
"errors"
+package cmd
- if err := func() error {
+ args = append([]string{"-d"}, args...)
"bytes"
-import (
+ "fmt"
- "bytes"
+ "io/fs"
"bytes"
- "bytes"
+ "io/fs"
"errors"
- "bytes"
+ if err != nil {
+ return err
+ "errors"
"fmt"
- "bytes"
"io/fs"
- "bytes"
"os"
- "bytes"
+ "io/fs"
"os/exec"
- "errors"
+ "os"
- "errors"
+ "os"
package cmd
"errors"
+ "bytes"
+ "os"
- "bytes"
+ "errors"
"fmt"
- "errors"
+ "os"
import (
- "errors"
+ "os"
"bytes"
- "errors"
+ "os"
"errors"
- "errors"
+ "os"
"fmt"
- "errors"
+ "os"
"io/fs"
- "bytes"
+ "errors"
"fmt"
- "errors"
+ if buf.String() == "" {
"os"
+ "os/exec"
- if err != nil {
+ return nil
- "bytes"
"errors"
- "bytes"
"fmt"
- "errors"
+
"os/exec"
+ "io/fs"
"fmt"
+ return err
- "bytes"
"errors"
- "bytes"
"fmt"
- "fmt"
+ "os/exec"
package cmd
+ "os/exec"
- return nil
+ return err
+ "errors"
"fmt"
+ cmd("git", "add", "--renormalize", apn)
+ return nil
+ }(); err != nil {
+ return err
+ "bytes"
"fmt"
-import (
}
}
diff --git a/cmd/rekey.go b/cmd/rekey.go
new file mode 100644
index 0000000000000000000000000000000000000000..bec71f73baea60f9bf57b66665a45bb10387ebbd
--- /dev/null
+++ b/cmd/rekey.go
@@ -0,0 +1,45 @@
+package cmd
+
+import (
+ "errors"
+ "fmt"
+ "io/fs"
+ "os"
+ "path/filepath"
+
+ "github.com/bmatcuk/doublestar/v4"
+ "github.com/urfave/cli/v2"
+)
+
+var Rekey = &cli.Command{
+ Name: "rekey",
+ Aliases: []string{"r"},
+ Description: "Re-key secrets",
+ Action: actionRekey,
+}
+
+func actionRekey(ctx *cli.Context) error {
+ cfg, err := LoadConfig()
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ return nil
+ }
+ return err
+ }
+ dir, err := gitBaseDir()
+ if err != nil {
+ return err
+ }
+ os.Setenv(REKEY, "1")
+ for glob := range cfg {
+ files, err := doublestar.FilepathGlob(glob, doublestar.WithFilesOnly())
+ if err != nil {
+ return fmt.Errorf("bad glob %q: %w", glob, err)
+ }
+ for _, file := range files {
+ cmd("git", "add", "--renormalize", filepath.Join(dir, file))
+ }
+ }
+
+ return nil
+}
diff --git a/go.mod b/go.mod
index ee578d6537f8e1128670f27de6200ce26a80c865..01a95d6c0a1fa06c0d8895162525ec359ace65c8 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ go 1.20
require (
filippo.io/age v1.1.1
+ github.com/bmatcuk/doublestar/v4 v4.6.0
github.com/urfave/cli/v2 v2.25.7
gopkg.in/yaml.v3 v3.0.1
lukechampine.com/blake3 v1.2.1
diff --git a/go.sum b/go.sum
index 884b7c4726586cd68401f59b50b0730060cc8eb3..cd9cf09d0829d7e8e1fe4937d4e6187a19934206 100644
--- a/go.sum
+++ b/go.sum
@@ -2,6 +2,8 @@ filippo.io/age v1.1.1 h1:pIpO7l151hCnQ4BdyBujnGP2YlUo0uj6sAVNHGBvXHg=
filippo.io/age v1.1.1/go.mod h1:l03SrzDUrBkdBx8+IILdnn2KZysqQdbEBUQ4p3sqEQE=
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
+github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc=
+github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=