summaryrefslogtreecommitdiff
path: root/cmd/rotate-credentials
diff options
context:
space:
mode:
authorChia <Chia@93.nz>2026-08-05 22:01:29 +1200
committerChia <Chia@93.nz>2026-08-05 22:07:50 +1200
commiteadb2ffe85c43cf6fc741c9823cd28eedb4a844c (patch)
tree1aba2536d57360da403aa35c9ced58b615c7064e /cmd/rotate-credentials
parentcd0dd91ab93653631904f2ea0e574ccde6d60339 (diff)
feat: harden prepaid billing and commercial operations
Diffstat (limited to '')
-rw-r--r--cmd/rotate-credentials/main.go41
1 files changed, 41 insertions, 0 deletions
diff --git a/cmd/rotate-credentials/main.go b/cmd/rotate-credentials/main.go
new file mode 100644
index 0000000..598035d
--- /dev/null
+++ b/cmd/rotate-credentials/main.go
@@ -0,0 +1,41 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "strings"
+ "time"
+
+ "aigw/internal/controlplane"
+)
+
+func main() {
+ databaseURL := strings.TrimSpace(os.Getenv("AIGW_DATABASE_URL"))
+ current := strings.TrimSpace(os.Getenv("AIGW_CREDENTIAL_KEY"))
+ previousRaw := os.Getenv("AIGW_CREDENTIAL_PREVIOUS_KEYS")
+ if databaseURL == "" || current == "" || strings.TrimSpace(previousRaw) == "" {
+ fmt.Fprintln(os.Stderr, "AIGW_DATABASE_URL, AIGW_CREDENTIAL_KEY, and AIGW_CREDENTIAL_PREVIOUS_KEYS are required")
+ os.Exit(2)
+ }
+ previous := []string{}
+ for _, value := range strings.Split(previousRaw, ",") {
+ if value = strings.TrimSpace(value); value != "" {
+ previous = append(previous, value)
+ }
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
+ defer cancel()
+ store, err := controlplane.NewStore(ctx, controlplane.Options{DatabaseURL: databaseURL, CredentialKey: current, PreviousCredentialKeys: previous})
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ defer store.Close()
+ count, err := store.RotateCredentials(ctx)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ fmt.Printf("re-encrypted %d credential records\n", count)
+}