@@ -20,6 +20,7 @@ import ( |
| 20 | 20 | "github.com/tenseleyFlow/shithub/internal/auth/password" |
| 21 | 21 | "github.com/tenseleyFlow/shithub/internal/auth/pat" |
| 22 | 22 | "github.com/tenseleyFlow/shithub/internal/auth/runnerjwt" |
| 23 | + "github.com/tenseleyFlow/shithub/internal/auth/sealbox" |
| 23 | 24 | "github.com/tenseleyFlow/shithub/internal/auth/secretbox" |
| 24 | 25 | "github.com/tenseleyFlow/shithub/internal/auth/session" |
| 25 | 26 | "github.com/tenseleyFlow/shithub/internal/auth/throttle" |
@@ -67,6 +68,26 @@ func buildAPIHandlers( |
| 67 | 68 | shithubdPath = abs |
| 68 | 69 | } |
| 69 | 70 | } |
| 71 | + // X25519 sealed-box keypair for the REST `actions/secrets/public-key` |
| 72 | + // endpoint. Loaded from config when present; auto-generated with a |
| 73 | + // loud warning otherwise (dev convenience — production deployments |
| 74 | + // MUST set the env knob so secrets survive process restart). |
| 75 | + var secretsBox *sealbox.Box |
| 76 | + if pk := cfg.Actions.Secrets.BoxPrivateKeyB64; pk != "" { |
| 77 | + b, err := sealbox.FromBase64(pk) |
| 78 | + if err != nil { |
| 79 | + return nil, fmt.Errorf("api: actions secrets box: %w", err) |
| 80 | + } |
| 81 | + secretsBox = b |
| 82 | + } else { |
| 83 | + b, err := sealbox.New() |
| 84 | + if err != nil { |
| 85 | + return nil, fmt.Errorf("api: actions secrets box (auto): %w", err) |
| 86 | + } |
| 87 | + logger.Warn("actions secrets box: auto-generated keypair; secrets PUT against this process will not be decryptable after restart", |
| 88 | + "hint", "set SHITHUB_ACTIONS__SECRETS__BOX_PRIVATE_KEY_B64=$(openssl rand -base64 32) for persistence") |
| 89 | + secretsBox = b |
| 90 | + } |
| 70 | 91 | return apih.New(apih.Deps{ |
| 71 | 92 | Pool: pool, |
| 72 | 93 | Debouncer: sharedPATDebouncer, |
@@ -75,6 +96,7 @@ func buildAPIHandlers( |
| 75 | 96 | RepoFS: rfs, |
| 76 | 97 | RunnerJWT: runnerJWT, |
| 77 | 98 | SecretBox: secretBox, |
| 99 | + SecretsBox: secretsBox, |
| 78 | 100 | RateLimiter: rateLimiter, |
| 79 | 101 | Audit: audit.NewRecorder(), |
| 80 | 102 | Throttle: throttle.NewLimiter(), |