package bootstrap /* * in order to be able to start up pomerium in case cloud is unreachable, * we store the minimum bootstrap configuration (essentially, the data broker connection) * in a file. this file is encrypted with a key that is derived from the cluster token. * * this information should be sufficient for pomerium to locate the database and start up. * */ import ( "context" "crypto/cipher" "encoding/json" "fmt" "os" "github.com/pomerium/pomerium/internal/zero/bootstrap/writers" "github.com/pomerium/pomerium/pkg/cryptutil" "github.com/pomerium/pomerium/pkg/health" cluster_api "github.com/pomerium/pomerium/pkg/zero/cluster" ) // LoadBootstrapConfigFromFile loads the bootstrap configuration from a file. func LoadBootstrapConfigFromFile(fp string, cipher cipher.AEAD) (*cluster_api.BootstrapConfig, error) { ciphertext, err := os.ReadFile(fp) if err != nil { return nil, fmt.Errorf("read bootstrap config: %w", err) } plaintext, err := cryptutil.Decrypt(cipher, ciphertext, nil) if err != nil { return nil, fmt.Errorf("decrypt bootstrap config: %w", err) } var dst cluster_api.BootstrapConfig err = json.Unmarshal(plaintext, &dst) if err != nil { return nil, fmt.Errorf("unmarshal bootstrap config: %w", err) } return &dst, nil } // SaveBootstrapConfig saves the bootstrap configuration to a file. func SaveBootstrapConfig(ctx context.Context, writer writers.ConfigWriter, src *cluster_api.BootstrapConfig) error { err := writer.WriteConfig(ctx, src) if err != nil { health.ReportError(health.ZeroBootstrapConfigSave, err) } else { health.ReportOK(health.ZeroBootstrapConfigSave) } return err }