Skip to content

Commit 5c9d7e3

Browse files
Merge pull request #79 from Infisical/PAM-12-add-k8s-support
feature: add k8s for PAM
2 parents 65eb1ac + 36bb8fa commit 5c9d7e3

File tree

10 files changed

+917
-112
lines changed

10 files changed

+917
-112
lines changed

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313
github.com/fatih/semgroup v1.2.0
1414
github.com/gitleaks/go-gitdiff v0.9.1
1515
github.com/go-mysql-org/go-mysql v1.13.0
16+
github.com/google/uuid v1.6.0
1617
github.com/h2non/filetype v1.1.3
1718
github.com/infisical/go-sdk v0.6.1
1819
github.com/infisical/infisical-kmip v0.3.17
@@ -104,14 +105,14 @@ require (
104105
github.com/google/gofuzz v1.2.0 // indirect
105106
github.com/google/pprof v0.0.0-20250302191652-9094ed2288e7 // indirect
106107
github.com/google/s2a-go v0.1.7 // indirect
107-
github.com/google/uuid v1.6.0 // indirect
108108
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
109109
github.com/googleapis/gax-go/v2 v2.12.5 // indirect
110110
github.com/gosimple/slug v1.15.0 // indirect
111111
github.com/gosimple/unidecode v1.0.1 // indirect
112112
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
113113
github.com/hashicorp/hcl v1.0.0 // indirect
114114
github.com/huandu/xstrings v1.5.0 // indirect
115+
github.com/imdario/mergo v0.3.6 // indirect
115116
github.com/josharian/intern v1.0.0 // indirect
116117
github.com/json-iterator/go v1.1.12 // indirect
117118
github.com/klauspost/compress v1.17.8 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI
346346
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
347347
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
348348
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
349+
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
350+
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
349351
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
350352
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
351353
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=

packages/api/model.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,8 @@ type PAMSessionCredentials struct {
823823
Password string `json:"password"`
824824
AuthMethod string `json:"authMethod,omitempty"`
825825
PrivateKey string `json:"privateKey,omitempty"`
826+
Url string `json:"url,omitempty"`
827+
ServiceAccountToken string `json:"serviceAccountToken,omitempty"`
826828
}
827829

828830
type UploadSessionLogEntry struct {
@@ -839,6 +841,17 @@ type UploadTerminalEvent struct {
839841
ElapsedTime float64 `json:"elapsedTime"`
840842
}
841843

844+
type UploadHttpEvent struct {
845+
Timestamp time.Time `json:"timestamp"`
846+
EventType string `json:"eventType"`
847+
RequestId string `json:"requestId"`
848+
Method string `json:"method,omitempty"`
849+
Url string `json:"url,omitempty"`
850+
Status string `json:"status,omitempty"`
851+
Headers map[string][]string `json:"headers,omitempty"`
852+
Body []byte `json:"body,omitempty"`
853+
}
854+
842855
type UploadPAMSessionLogsRequest struct {
843856
Logs interface{} `json:"logs"` // Can be []UploadSessionLogEntry or []UploadTerminalEvent
844857
}

packages/cmd/pam.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,76 @@ var pamSshAccessAccountCmd = &cobra.Command{
151151
pam.StartSSHLocalProxy(loggedInUserDetails.UserCredentials.JTWToken, accountPath, projectID, durationStr)
152152
},
153153
}
154+
var pamKubernetesCmd = &cobra.Command{
155+
Use: "kubernetes",
156+
Aliases: []string{"k8s"},
157+
Short: "Kubernetes-related PAM commands",
158+
Long: "Kubernetes-related PAM commands for Infisical",
159+
DisableFlagsInUseLine: true,
160+
Args: cobra.NoArgs,
161+
}
162+
163+
var pamKubernetesAccessAccountCmd = &cobra.Command{
164+
Use: "access-account <account-path>",
165+
Short: "Access Kubernetes PAM account",
166+
Long: "Access Kubernetes via a PAM-managed Kubernetes account. This command automatically launches a proxy connected to your Kubernetes cluster through the Infisical Gateway.",
167+
Example: "infisical pam kubernetes access-account prod/ssh/my-k8s-account --duration 2h",
168+
DisableFlagsInUseLine: true,
169+
Args: cobra.ExactArgs(1),
170+
Run: func(cmd *cobra.Command, args []string) {
171+
util.RequireLogin()
172+
173+
accountPath := args[0]
174+
175+
durationStr, err := cmd.Flags().GetString("duration")
176+
if err != nil {
177+
util.HandleError(err, "Unable to parse duration flag")
178+
}
179+
180+
// Parse duration
181+
_, err = time.ParseDuration(durationStr)
182+
if err != nil {
183+
util.HandleError(err, "Invalid duration format. Use formats like '1h', '30m', '2h30m'")
184+
}
185+
186+
port, err := cmd.Flags().GetInt("port")
187+
if err != nil {
188+
util.HandleError(err, "Unable to parse port flag")
189+
}
190+
191+
projectID, err := cmd.Flags().GetString("project-id")
192+
if err != nil {
193+
util.HandleError(err, "Unable to parse project-id flag")
194+
}
195+
196+
if projectID == "" {
197+
workspaceFile, err := util.GetWorkSpaceFromFile()
198+
if err != nil {
199+
util.PrintErrorMessageAndExit("Please either run infisical init to connect to a project or pass in project id with --project-id flag")
200+
}
201+
projectID = workspaceFile.WorkspaceId
202+
}
203+
204+
log.Debug().Msg("PAM Kubernetes Access: Trying to fetch credentials using logged in details")
205+
206+
loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true)
207+
isConnected := util.ValidateInfisicalAPIConnection()
208+
209+
if isConnected {
210+
log.Debug().Msg("PAM Kubernetes Access: Connected to Infisical instance, checking logged in creds")
211+
}
212+
213+
if err != nil {
214+
util.HandleError(err, "Unable to get logged in user details")
215+
}
216+
217+
if isConnected && loggedInUserDetails.LoginExpired {
218+
loggedInUserDetails = util.EstablishUserLoginSession()
219+
}
220+
221+
pam.StartKubernetesLocalProxy(loggedInUserDetails.UserCredentials.JTWToken, accountPath, projectID, durationStr, port)
222+
},
223+
}
154224

155225
func init() {
156226
pamDbCmd.AddCommand(pamDbAccessAccountCmd)
@@ -162,7 +232,13 @@ func init() {
162232
pamSshAccessAccountCmd.Flags().String("duration", "1h", "Duration for SSH access session (e.g., '1h', '30m', '2h30m')")
163233
pamSshAccessAccountCmd.Flags().String("project-id", "", "Project ID of the account to access")
164234

235+
pamKubernetesCmd.AddCommand(pamKubernetesAccessAccountCmd)
236+
pamKubernetesAccessAccountCmd.Flags().String("duration", "1h", "Duration for kubernetes access session (e.g., '1h', '30m', '2h30m')")
237+
pamKubernetesAccessAccountCmd.Flags().Int("port", 0, "Port for the local kubernetes proxy server (0 for auto-assign)")
238+
pamKubernetesAccessAccountCmd.Flags().String("project-id", "", "Project ID of the account to access")
239+
165240
pamCmd.AddCommand(pamDbCmd)
166241
pamCmd.AddCommand(pamSshCmd)
242+
pamCmd.AddCommand(pamKubernetesCmd)
167243
rootCmd.AddCommand(pamCmd)
168244
}

0 commit comments

Comments
 (0)