Skip to content

Commit 532fcc3

Browse files
Merge pull request #24 from Infisical/feat/pam-setup-and-progress
feat: PAM scaffolding + Postgres PAM access
2 parents c5d91f5 + 5f82b89 commit 532fcc3

File tree

15 files changed

+2765
-28
lines changed

15 files changed

+2765
-28
lines changed

go.mod

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/h2non/filetype v1.1.3
1717
github.com/infisical/go-sdk v0.5.99
1818
github.com/infisical/infisical-kmip v0.3.5
19+
github.com/jackc/pgx/v5 v5.7.6
1920
github.com/mattn/go-isatty v0.0.20
2021
github.com/muesli/ansi v0.0.0-20221106050444-61f0cd9a192a
2122
github.com/muesli/mango-cobra v1.2.0
@@ -34,10 +35,10 @@ require (
3435
github.com/spf13/viper v1.8.1
3536
github.com/stretchr/testify v1.10.0
3637
github.com/wasilibs/go-re2 v1.10.0
37-
golang.org/x/crypto v0.36.0
38+
golang.org/x/crypto v0.37.0
3839
golang.org/x/exp v0.0.0-20250228200357-dead58393ab7
39-
golang.org/x/sys v0.31.0
40-
golang.org/x/term v0.30.0
40+
golang.org/x/sys v0.32.0
41+
golang.org/x/term v0.31.0
4142
gopkg.in/yaml.v2 v2.4.0
4243
gopkg.in/yaml.v3 v3.0.1
4344
k8s.io/api v0.31.4
@@ -152,8 +153,8 @@ require (
152153
golang.org/x/mod v0.23.0 // indirect
153154
golang.org/x/net v0.38.0 // indirect
154155
golang.org/x/oauth2 v0.27.0 // indirect
155-
golang.org/x/sync v0.12.0 // indirect
156-
golang.org/x/text v0.23.0 // indirect
156+
golang.org/x/sync v0.13.0 // indirect
157+
golang.org/x/text v0.24.0 // indirect
157158
golang.org/x/time v0.9.0 // indirect
158159
golang.org/x/tools v0.30.0 // indirect
159160
google.golang.org/api v0.188.0 // indirect

go.sum

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,12 @@ github.com/infisical/go-sdk v0.5.99 h1:trvn7JhKYuSzDkc44h+yqToVjclkrRyP42t315k5k
316316
github.com/infisical/go-sdk v0.5.99/go.mod h1:j2D2a5WPNdKXDfHO+3y/TNyLWh5Aq9QYS7EcGI96LZI=
317317
github.com/infisical/infisical-kmip v0.3.5 h1:QM3s0e18B+mYv3a9HQNjNAlbwZJBzXq5BAJM2scIeiE=
318318
github.com/infisical/infisical-kmip v0.3.5/go.mod h1:bO1M4YtKyutNg1bREPmlyZspC5duSR7hyQ3lPmLzrIs=
319+
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
320+
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
321+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
322+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
323+
github.com/jackc/pgx/v5 v5.7.6 h1:rWQc5FwZSPX58r1OQmkuaNicxdmExaEz5A2DO2hUuTk=
324+
github.com/jackc/pgx/v5 v5.7.6/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
319325
github.com/jedib0t/go-pretty v4.3.0+incompatible h1:CGs8AVhEKg/n9YbUenWmNStRW2PHJzaeDodcfvRAbIo=
320326
github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag=
321327
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -562,8 +568,8 @@ golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5
562568
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
563569
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
564570
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
565-
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
566-
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
571+
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
572+
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
567573
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
568574
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
569575
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -676,8 +682,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
676682
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
677683
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
678684
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
679-
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
680-
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
685+
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
686+
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
681687
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
682688
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
683689
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -733,16 +739,16 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
733739
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
734740
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
735741
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
736-
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
737-
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
742+
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
743+
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
738744
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
739745
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
740746
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
741747
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
742748
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
743749
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
744-
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
745-
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
750+
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
751+
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
746752
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
747753
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
748754
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -755,8 +761,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
755761
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
756762
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
757763
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
758-
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
759-
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
764+
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
765+
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
760766
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
761767
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
762768
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

packages/api/api.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package api
22

33
import (
4+
"encoding/base64"
45
"fmt"
56
"net/http"
67
"strings"
@@ -44,6 +45,11 @@ const (
4445
operationCallRegisterInstanceRelay = "CallRegisterInstanceRelay"
4546
operationCallRegisterOrgRelay = "CallRegisterOrgRelay"
4647
operationCallRegisterGateway = "CallRegisterGateway"
48+
operationCallPAMAccess = "CallPAMAccess"
49+
operationCallPAMSessionCredentials = "CallPAMSessionCredentials"
50+
operationCallGetPamSessionKey = "CallGetPamSessionKey"
51+
operationCallUploadPamSessionLog = "CallUploadPamSessionLog"
52+
operationCallPAMSessionTermination = "CallPAMSessionTermination"
4753
)
4854

4955
func CallGetEncryptedWorkspaceKey(httpClient *resty.Client, request GetEncryptedWorkspaceKeyRequest) (GetEncryptedWorkspaceKeyResponse, error) {
@@ -752,3 +758,94 @@ func CallRegisterGateway(httpClient *resty.Client, request RegisterGatewayReques
752758

753759
return resBody, nil
754760
}
761+
762+
func CallPAMAccess(httpClient *resty.Client, request PAMAccessRequest) (PAMAccessResponse, error) {
763+
var pamAccessResponse PAMAccessResponse
764+
response, err := httpClient.
765+
R().
766+
SetResult(&pamAccessResponse).
767+
SetHeader("User-Agent", USER_AGENT).
768+
SetBody(request).
769+
Post(fmt.Sprintf("%v/v1/pam/accounts/access", config.INFISICAL_URL))
770+
771+
if err != nil {
772+
return PAMAccessResponse{}, NewGenericRequestError(operationCallPAMAccess, err)
773+
}
774+
775+
if response.IsError() {
776+
return PAMAccessResponse{}, NewAPIErrorWithResponse(operationCallPAMAccess, response, nil)
777+
}
778+
779+
return pamAccessResponse, nil
780+
}
781+
782+
func CallPAMSessionCredentials(httpClient *resty.Client, sessionId string) (PAMSessionCredentialsResponse, error) {
783+
var pamSessionCredentialsResponse PAMSessionCredentialsResponse
784+
response, err := httpClient.
785+
R().
786+
SetResult(&pamSessionCredentialsResponse).
787+
SetHeader("User-Agent", USER_AGENT).
788+
Get(fmt.Sprintf("%v/v1/pam/sessions/%s/credentials", config.INFISICAL_URL, sessionId))
789+
790+
if err != nil {
791+
return PAMSessionCredentialsResponse{}, NewGenericRequestError(operationCallPAMSessionCredentials, err)
792+
}
793+
794+
if response.IsError() {
795+
return PAMSessionCredentialsResponse{}, NewAPIErrorWithResponse(operationCallPAMSessionCredentials, response, nil)
796+
}
797+
798+
return pamSessionCredentialsResponse, nil
799+
}
800+
801+
func CallGetPamSessionKey(httpClient *resty.Client) (string, error) {
802+
response, err := httpClient.
803+
R().
804+
SetHeader("User-Agent", USER_AGENT).
805+
Get(fmt.Sprintf("%v/v2/gateways/pam-session-key", config.INFISICAL_URL))
806+
807+
if err != nil {
808+
return "", NewGenericRequestError(operationCallGetPamSessionKey, err)
809+
}
810+
811+
if response.IsError() {
812+
return "", NewAPIErrorWithResponse(operationCallGetPamSessionKey, response, nil)
813+
}
814+
815+
return base64.StdEncoding.EncodeToString(response.Body()), nil
816+
}
817+
818+
func CallUploadPamSessionLogs(httpClient *resty.Client, sessionId string, request UploadPAMSessionLogsRequest) error {
819+
response, err := httpClient.
820+
R().
821+
SetHeader("User-Agent", USER_AGENT).
822+
SetBody(request).
823+
Post(fmt.Sprintf("%v/v1/pam/sessions/%s/logs", config.INFISICAL_URL, sessionId))
824+
825+
if err != nil {
826+
return NewGenericRequestError(operationCallUploadPamSessionLog, err)
827+
}
828+
829+
if response.IsError() {
830+
return NewAPIErrorWithResponse(operationCallUploadPamSessionLog, response, nil)
831+
}
832+
833+
return nil
834+
}
835+
836+
func CallPAMSessionTermination(httpClient *resty.Client, sessionId string) error {
837+
response, err := httpClient.
838+
R().
839+
SetHeader("User-Agent", USER_AGENT).
840+
Post(fmt.Sprintf("%v/v1/pam/sessions/%s/end", config.INFISICAL_URL, sessionId))
841+
842+
if err != nil {
843+
return NewGenericRequestError(operationCallPAMSessionTermination, err)
844+
}
845+
846+
if response.IsError() {
847+
return NewAPIErrorWithResponse(operationCallPAMSessionTermination, response, nil)
848+
}
849+
850+
return nil
851+
}

packages/api/model.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,3 +741,45 @@ type RegisterGatewayResponse struct {
741741
ServerCAPublicKey string `json:"serverCAPublicKey"`
742742
} `json:"ssh"`
743743
}
744+
745+
type PAMAccessRequest struct {
746+
Duration string `json:"duration,omitempty"`
747+
AccountId string `json:"accountId,omitempty"`
748+
}
749+
750+
type PAMAccessResponse struct {
751+
SessionId string `json:"sessionId"`
752+
ResourceType string `json:"resourceType"`
753+
RelayClientCertificate string `json:"relayClientCertificate"`
754+
RelayClientPrivateKey string `json:"relayClientPrivateKey"`
755+
RelayServerCertificateChain string `json:"relayServerCertificateChain"`
756+
GatewayClientCertificate string `json:"gatewayClientCertificate"`
757+
GatewayClientPrivateKey string `json:"gatewayClientPrivateKey"`
758+
GatewayServerCertificateChain string `json:"gatewayServerCertificateChain"`
759+
RelayHost string `json:"relayHost"`
760+
}
761+
762+
type PAMSessionCredentialsResponse struct {
763+
Credentials PAMSessionCredentials `json:"credentials"`
764+
}
765+
766+
type PAMSessionCredentials struct {
767+
Host string `json:"host"`
768+
Port int `json:"port"`
769+
Database string `json:"database"`
770+
SSLEnabled bool `json:"sslEnabled"`
771+
SSLRejectUnauthorized bool `json:"sslRejectUnauthorized"`
772+
SSLCertificate string `json:"sslCertificate,omitempty"`
773+
Username string `json:"username"`
774+
Password string `json:"password"`
775+
}
776+
777+
type UploadSessionLogEntry struct {
778+
Timestamp time.Time `json:"timestamp"`
779+
Input string `json:"input"`
780+
Output string `json:"output"`
781+
}
782+
783+
type UploadPAMSessionLogsRequest struct {
784+
Logs []UploadSessionLogEntry `json:"logs"`
785+
}

packages/cmd/gateway.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/Infisical/infisical-merge/packages/config"
1616
"github.com/Infisical/infisical-merge/packages/gateway"
1717
gatewayv2 "github.com/Infisical/infisical-merge/packages/gateway-v2"
18+
"github.com/Infisical/infisical-merge/packages/pam/session"
1819
"github.com/Infisical/infisical-merge/packages/util"
1920
infisicalSdk "github.com/infisical/go-sdk"
2021
"github.com/pkg/errors"
@@ -219,6 +220,11 @@ var gatewayStartCmd = &cobra.Command{
219220
util.HandleError(err, fmt.Sprintf("unable to get name flag or %s env", gatewayv2.GATEWAY_NAME_ENV_NAME))
220221
}
221222

223+
pamSessionRecordingPath, err := util.GetCmdFlagOrEnv(cmd, "pam-session-recording-path", []string{gatewayv2.INFISICAL_PAM_SESSION_RECORDING_PATH_ENV_NAME})
224+
if err == nil && pamSessionRecordingPath != "" {
225+
session.SetSessionRecordingPath(pamSessionRecordingPath)
226+
}
227+
222228
gatewayInstance, err := gatewayv2.NewGateway(&gatewayv2.GatewayConfig{
223229
Name: gatewayName,
224230
RelayName: relayName,
@@ -508,6 +514,7 @@ func init() {
508514
gatewayStartCmd.Flags().String("service-account-token-path", "", "service account token path for kubernetes auth")
509515
gatewayStartCmd.Flags().String("service-account-key-file-path", "", "service account key file path for GCP IAM auth")
510516
gatewayStartCmd.Flags().String("jwt", "", "JWT for jwt-based auth methods [oidc-auth, jwt-auth]")
517+
gatewayStartCmd.Flags().String("pam-session-recording-path", "", "directory path for PAM session recordings (defaults to /var/lib/infisical/session_recordings)")
511518

512519
// Legacy install command flags (v1)
513520
gatewayInstallCmd.Flags().String("token", "", "Connect with Infisical using machine identity access token")

packages/cmd/pam.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package cmd
2+
3+
import (
4+
"time"
5+
6+
"github.com/Infisical/infisical-merge/packages/util"
7+
"github.com/rs/zerolog/log"
8+
"github.com/spf13/cobra"
9+
10+
"github.com/Infisical/infisical-merge/packages/pam"
11+
)
12+
13+
var pamCmd = &cobra.Command{
14+
Use: "pam",
15+
Short: "PAM-related commands",
16+
Long: "PAM-related commands for Infisical",
17+
DisableFlagsInUseLine: true,
18+
Args: cobra.NoArgs,
19+
}
20+
21+
var pamDbCmd = &cobra.Command{
22+
Use: "db",
23+
Short: "Database-related PAM commands",
24+
Long: "Database-related PAM commands for Infisical",
25+
DisableFlagsInUseLine: true,
26+
Args: cobra.NoArgs,
27+
}
28+
29+
var pamDbAccessAccountCmd = &cobra.Command{
30+
Use: "access-account <account-name-or-id>",
31+
Short: "Access PAM database accounts",
32+
Long: "Access PAM database accounts for Infisical. This starts a local database proxy server that you can use to connect to databases directly.",
33+
Example: "infisical pam db access-account my-postgres-account --duration 4h --port 5432",
34+
DisableFlagsInUseLine: true,
35+
Args: cobra.ExactArgs(1),
36+
Run: func(cmd *cobra.Command, args []string) {
37+
util.RequireLogin()
38+
39+
accountID := args[0]
40+
41+
durationStr, err := cmd.Flags().GetString("duration")
42+
if err != nil {
43+
util.HandleError(err, "Unable to parse duration flag")
44+
}
45+
46+
// Parse duration
47+
_, err = time.ParseDuration(durationStr)
48+
if err != nil {
49+
util.HandleError(err, "Invalid duration format. Use formats like '1h', '30m', '2h30m'")
50+
}
51+
52+
port, err := cmd.Flags().GetInt("port")
53+
if err != nil {
54+
util.HandleError(err, "Unable to parse port flag")
55+
}
56+
57+
log.Debug().Msg("PAM Database Access: Trying to fetch secrets using logged in details")
58+
59+
loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true)
60+
isConnected := util.ValidateInfisicalAPIConnection()
61+
62+
if isConnected {
63+
log.Debug().Msg("PAM Database Access: Connected to Infisical instance, checking logged in creds")
64+
}
65+
66+
if err != nil {
67+
util.HandleError(err, "Unable to get logged in user details")
68+
}
69+
70+
if isConnected && loggedInUserDetails.LoginExpired {
71+
loggedInUserDetails = util.EstablishUserLoginSession()
72+
}
73+
74+
pam.StartDatabaseLocalProxy(loggedInUserDetails.UserCredentials.JTWToken, accountID, durationStr, port)
75+
},
76+
}
77+
78+
func init() {
79+
pamDbCmd.AddCommand(pamDbAccessAccountCmd)
80+
pamDbAccessAccountCmd.Flags().String("duration", "1h", "Duration for database access session (e.g., '1h', '30m', '2h30m')")
81+
pamDbAccessAccountCmd.Flags().Int("port", 0, "Port for the local database proxy server (0 for auto-assign)")
82+
83+
pamCmd.AddCommand(pamDbCmd)
84+
rootCmd.AddCommand(pamCmd)
85+
}

packages/gateway-v2/constants.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package gatewayv2
22

33
const (
4-
KUBERNETES_SERVICE_HOST_ENV_NAME = "KUBERNETES_SERVICE_HOST"
5-
KUBERNETES_SERVICE_PORT_HTTPS_ENV_NAME = "KUBERNETES_SERVICE_PORT_HTTPS"
6-
KUBERNETES_SERVICE_ACCOUNT_CA_CERT_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
7-
KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/token"
4+
KUBERNETES_SERVICE_HOST_ENV_NAME = "KUBERNETES_SERVICE_HOST"
5+
KUBERNETES_SERVICE_PORT_HTTPS_ENV_NAME = "KUBERNETES_SERVICE_PORT_HTTPS"
6+
KUBERNETES_SERVICE_ACCOUNT_CA_CERT_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
7+
KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/token"
8+
INFISICAL_PAM_SESSION_RECORDING_PATH_ENV_NAME = "INFISICAL_PAM_SESSION_RECORDING_PATH"
89

910
RELAY_NAME_ENV_NAME = "INFISICAL_RELAY_NAME"
1011
RELAY_HOST_ENV_NAME = "INFISICAL_RELAY_HOST"

0 commit comments

Comments
 (0)