Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/govulncheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@7b8cf10d4e4a01d4992d18a89f4d7dc5a3e6d6f4 # v4.3.0
with:
go-version: "1.25.12"
go-version: "1.26.6"
cache: true
cache-dependency-path: go.sum
- name: Install govulncheck
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release_build_infisical_cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ jobs:
- run: echo "Ref name ${{github.ref_name}}"
- uses: actions/setup-go@be3c94b385c4f180051c996d336f57a34c397495 # v3.6.1
with:
go-version: "1.25.12"
go-version: "1.26.6"
cache: true
cache-dependency-path: go.sum
- name: Setup for libssl1.0-dev
Expand Down Expand Up @@ -394,7 +394,7 @@ jobs:

- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version: "1.25.12"
go-version: "1.26.6"
cache: true
cache-dependency-path: go.sum

Expand Down Expand Up @@ -474,7 +474,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@be3c94b385c4f180051c996d336f57a34c397495 # v3.6.1
with:
go-version: "1.25.12"
go-version: "1.26.6"
cache: true
cache-dependency-path: go.sum

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/run-cli-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: "1.25.12"
go-version: "1.26.6"
- name: Install dependencies
run: go get .
- name: Build the CLI
Expand Down Expand Up @@ -52,7 +52,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: "1.25.12"
go-version: "1.26.6"
- name: Install dependencies
run: go get .
- name: Build the CLI
Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: "1.25.12"
go-version: "1.26.6"
- name: Install dependencies
run: go get .
- name: Cache cargo registry + target
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-cli-smoke-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version: "1.25.12"
go-version: "1.26.6"

- name: Cache cargo registry + target
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-cli-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@7b8cf10d4e4a01d4992d18a89f4d7dc5a3e6d6f4 # v4.3.0
with:
go-version: "1.25.12"
go-version: "1.26.6"
- name: Install dependencies
run: go get .
- name: Test with the Go CLI
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/test-update-instructions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- uses: actions/setup-go@7b8cf10d4e4a01d4992d18a89f4d7dc5a3e6d6f4 # v4.3.0
with:
go-version: "1.25.12"
go-version: "1.26.6"
- name: Run unit tests
run: go test ./packages/util/ -run TestGetUpdateInstructions -v

Expand All @@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- uses: actions/setup-go@7b8cf10d4e4a01d4992d18a89f4d7dc5a3e6d6f4 # v4.3.0
with:
go-version: "1.25.12"
go-version: "1.26.6"
- name: Build test helper
run: go build -o update-hint.exe ./test/update-hint

Expand Down Expand Up @@ -70,7 +70,7 @@ jobs:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- uses: actions/setup-go@7b8cf10d4e4a01d4992d18a89f4d7dc5a3e6d6f4 # v4.3.0
with:
go-version: "1.25.12"
go-version: "1.26.6"
- name: Build test helper
run: go build -o update-hint ./test/update-hint

Expand All @@ -97,7 +97,7 @@ jobs:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- uses: actions/setup-go@7b8cf10d4e4a01d4992d18a89f4d7dc5a3e6d6f4 # v4.3.0
with:
go-version: "1.25.12"
go-version: "1.26.6"
- name: Build test helper
run: go build -o update-hint ./test/update-hint

Expand Down
4 changes: 2 additions & 2 deletions e2e/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/infisical/cli/e2e-tests

go 1.25.12
go 1.26.6

require (
github.com/Infisical/infisical-merge v0.0.0
Expand Down Expand Up @@ -168,7 +168,7 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/indece-official/go-ebcdic v1.2.0 // indirect
github.com/infisical/go-sdk v0.7.0 // indirect
github.com/infisical/infisical-kmip v0.3.19 // indirect
github.com/infisical/infisical-kmip v0.3.20-0.20260808014015-39f64ec76f78 // indirect
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
Expand Down
4 changes: 2 additions & 2 deletions e2e/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,8 @@ github.com/indece-official/go-ebcdic v1.2.0 h1:nKCubkNoXrGvBp3MSYuplOQnhANCDEY51
github.com/indece-official/go-ebcdic v1.2.0/go.mod h1:RBddVJt0Ks0eDLRG5dhPwBDRiTNA7n+yv0dVFpSs46Q=
github.com/infisical/go-sdk v0.7.0 h1:x9/1PczL+ioVD1jCp4LHQzPpBawatbmkjAC0S1OAtUA=
github.com/infisical/go-sdk v0.7.0/go.mod h1:yEfXF+3YDDXiJ9zzJUSzW6me6XXPPEDK52fSU6JfpCA=
github.com/infisical/infisical-kmip v0.3.19 h1:JDndxhM9+GoHTqSOX47H3KIxIuDmrEHsq17wvhw3RL8=
github.com/infisical/infisical-kmip v0.3.19/go.mod h1:bO1M4YtKyutNg1bREPmlyZspC5duSR7hyQ3lPmLzrIs=
github.com/infisical/infisical-kmip v0.3.20-0.20260808014015-39f64ec76f78 h1:p145uaPRke7N1kP5lMcO/XX/OOosHhQ2JS3095aQVhM=
github.com/infisical/infisical-kmip v0.3.20-0.20260808014015-39f64ec76f78/go.mod h1:bO1M4YtKyutNg1bREPmlyZspC5duSR7hyQ3lPmLzrIs=
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s=
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/Infisical/infisical-merge

go 1.25.12
go 1.26.6

require (
github.com/Azure/go-ntlmssp v0.1.1
Expand All @@ -23,7 +23,7 @@ require (
github.com/google/uuid v1.6.0
github.com/h2non/filetype v1.1.3
github.com/infisical/go-sdk v0.7.0
github.com/infisical/infisical-kmip v0.3.19
github.com/infisical/infisical-kmip v0.3.20-0.20260808014015-39f64ec76f78
github.com/jackc/pgx/v5 v5.9.2
github.com/jcmturner/gokrb5/v8 v8.4.4
github.com/masterzen/winrm v0.0.0-20260407182533-5570be7f80cf
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ github.com/indece-official/go-ebcdic v1.2.0 h1:nKCubkNoXrGvBp3MSYuplOQnhANCDEY51
github.com/indece-official/go-ebcdic v1.2.0/go.mod h1:RBddVJt0Ks0eDLRG5dhPwBDRiTNA7n+yv0dVFpSs46Q=
github.com/infisical/go-sdk v0.7.0 h1:x9/1PczL+ioVD1jCp4LHQzPpBawatbmkjAC0S1OAtUA=
github.com/infisical/go-sdk v0.7.0/go.mod h1:yEfXF+3YDDXiJ9zzJUSzW6me6XXPPEDK52fSU6JfpCA=
github.com/infisical/infisical-kmip v0.3.19 h1:JDndxhM9+GoHTqSOX47H3KIxIuDmrEHsq17wvhw3RL8=
github.com/infisical/infisical-kmip v0.3.19/go.mod h1:bO1M4YtKyutNg1bREPmlyZspC5duSR7hyQ3lPmLzrIs=
github.com/infisical/infisical-kmip v0.3.20-0.20260808014015-39f64ec76f78 h1:p145uaPRke7N1kP5lMcO/XX/OOosHhQ2JS3095aQVhM=
github.com/infisical/infisical-kmip v0.3.20-0.20260808014015-39f64ec76f78/go.mod h1:bO1M4YtKyutNg1bREPmlyZspC5duSR7hyQ3lPmLzrIs=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
Expand Down
53 changes: 47 additions & 6 deletions packages/cmd/kmip.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ Copyright (c) 2023 Infisical Inc.
package cmd

import (
"context"
"errors"
"fmt"
"os"
"os/exec"
"runtime"
"time"

"github.com/Infisical/infisical-merge/packages/api"
"github.com/Infisical/infisical-merge/packages/config"
Expand Down Expand Up @@ -128,7 +130,7 @@ func startKmipServer(cmd *cobra.Command, args []string) {

isResourceAuth := enrollMethod == localkmip.EnrollMethodToken || enrollMethod == localkmip.EnrollMethodAws
if isResourceAuth {
serverConfig.AccessToken = enrollKmipServer(cmd, enrollMethod, serverName)
serverConfig.AccessToken, serverConfig.RefreshAccessToken = enrollKmipServer(cmd, enrollMethod, serverName)
} else {
// No enroll method given: reuse the stored enrollment access token unless explicit identity
// credentials were passed. This keeps a manual restart of an enrolled server from silently
Expand All @@ -138,6 +140,9 @@ func startKmipServer(cmd *cobra.Command, args []string) {
if storedToken, _ := localkmip.LoadStoredAccessToken(serverName); storedToken != "" {
log.Info().Msg("Using stored KMIP server access token")
serverConfig.AccessToken = storedToken
if serverID, canRefresh := localkmip.ResolveAwsRefreshServerID(serverName); canRefresh {
serverConfig.RefreshAccessToken = newAwsRefreshAccessTokenFunc(serverName, serverID)
}
}
}
if serverConfig.AccessToken == "" {
Expand All @@ -148,9 +153,38 @@ func startKmipServer(cmd *cobra.Command, args []string) {
kmip.StartServer(serverConfig)
}

// newAwsRefreshAccessTokenFunc returns a function that re-authenticates the KMIP server via
// AWS STS and persists the new access token, used by the renewal loop when the current token
// is rejected. Bounded timeouts so a hung API call cannot stall renewal indefinitely.
func newAwsRefreshAccessTokenFunc(serverName, kmipServerID string) func() (string, error) {
return func() (string, error) {
refreshClient, err := util.GetRestyClientWithCustomHeaders()
if err != nil {
return "", fmt.Errorf("unable to create HTTP client: %w", err)
}
refreshClient.SetTimeout(30 * time.Second)

ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

newToken, err := localkmip.LoginKmipServerWithAws(ctx, refreshClient, kmipServerID)
if err != nil {
return "", fmt.Errorf("AWS Auth re-login failed: %w", err)
}

if err := localkmip.SaveAccessToken(serverName, newToken); err != nil {
log.Warn().Msgf("failed to persist refreshed KMIP access token: %v", err)
}

return newToken, nil
}
}

// enrollKmipServer obtains a KMIP server access token via token or AWS enrollment,
// persisting the relevant state under the KMIP server's config file.
func enrollKmipServer(cmd *cobra.Command, enrollMethod, serverName string) string {
// persisting the relevant state under the KMIP server's config file. For AWS enrollment it
// also returns a refresh function so the server can re-authenticate when its access token
// expires before its certificate does; token enrollment is single-use, so no refresh exists.
func enrollKmipServer(cmd *cobra.Command, enrollMethod, serverName string) (string, func() (string, error)) {
httpClient, err := util.GetRestyClientWithCustomHeaders()
if err != nil {
util.HandleError(err, "unable to create HTTP client")
Expand Down Expand Up @@ -178,12 +212,16 @@ func enrollKmipServer(cmd *cobra.Command, enrollMethod, serverName string) strin
if err := localkmip.SaveServerID(serverName, kmipServerID); err != nil {
util.HandleError(err, "failed to save KMIP server id to config")
}
if err := localkmip.SaveEnrollMethod(serverName, localkmip.EnrollMethodAws); err != nil {
util.HandleError(err, "failed to save KMIP enroll method to config")
}
if err := localkmip.SaveDomain(serverName, config.INFISICAL_URL); err != nil {
util.HandleError(err, "failed to save domain to config")
}

log.Info().Msgf("KMIP server authenticated via AWS Auth. State saved to %s", localkmip.GetConfPathDisplay(serverName))
return accessToken

return accessToken, newAwsRefreshAccessTokenFunc(serverName, kmipServerID)
}

// Enrollment token path
Expand All @@ -197,7 +235,7 @@ func enrollKmipServer(cmd *cobra.Command, enrollMethod, serverName string) strin
storedAccessToken, err := localkmip.LoadStoredAccessToken(serverName)
if err == nil && storedAccessToken != "" {
log.Info().Msg("Reusing stored KMIP server access token.")
return storedAccessToken
return storedAccessToken, nil
}
if enrollToken == "" {
util.HandleError(errors.New("--token is required when --enroll-method=token and no access token is stored"))
Expand All @@ -220,6 +258,9 @@ func enrollKmipServer(cmd *cobra.Command, enrollMethod, serverName string) strin
if err := localkmip.SaveAccessToken(serverName, enrollResp.AccessToken); err != nil {
util.HandleError(err, "failed to save KMIP server access token")
}
if err := localkmip.SaveEnrollMethod(serverName, localkmip.EnrollMethodToken); err != nil {
util.HandleError(err, "failed to save KMIP enroll method to config")
}
if err := localkmip.SaveEnrollmentToken(serverName, enrollToken); err != nil {
util.HandleError(err, "failed to save enrollment token to config")
}
Expand All @@ -228,7 +269,7 @@ func enrollKmipServer(cmd *cobra.Command, enrollMethod, serverName string) strin
}

log.Info().Msgf("KMIP server enrolled successfully. Access token saved to %s", localkmip.GetConfPathDisplay(serverName))
return enrollResp.AccessToken
return enrollResp.AccessToken, nil
}

// resolveKmipIdentityCredentials parses the legacy machine-identity credentials.
Expand Down
25 changes: 25 additions & 0 deletions packages/kmip/enroll.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,31 @@ func SaveServerID(name, kmipServerID string) error {
return saveConfKey(name, INFISICAL_KMIP_SERVER_ID_KEY, kmipServerID)
}

// Conf-file only: the env var says what this run asked for, not how the server enrolled.
func LoadStoredEnrollMethod(name string) (string, error) {
return loadConfKey(name, INFISICAL_KMIP_ENROLL_METHOD_KEY)
}

func SaveEnrollMethod(name, method string) error {
return saveConfKey(name, INFISICAL_KMIP_ENROLL_METHOD_KEY, method)
}

func LoadPersistedServerID(name string) (string, error) {
return loadConfKey(name, INFISICAL_KMIP_SERVER_ID_KEY)
}

// Ignores the environment throughout: honouring INFISICAL_KMIP_SERVER_ID here would wire a
// token-enrolled server for an STS refresh it cannot perform. A missing method means the server
// enrolled before it was recorded, where a conf-file server ID identifies AWS enrollment.
func ResolveAwsRefreshServerID(name string) (string, bool) {
method, _ := LoadStoredEnrollMethod(name)
serverID, _ := LoadPersistedServerID(name)
if serverID == "" {
return "", false
}
return serverID, method == EnrollMethodAws || method == ""
}

func GetConfPathDisplay(name string) string {
path, err := kmipConfPath(name)
if err != nil {
Expand Down
Loading
Loading