├── .github
└── workflows
│ └── build-lint.yml
├── .gitignore
├── LICENSE
├── README.md
├── auth.go
├── bin
└── golangci-lint
├── client.go
├── dynamic_secrets.go
├── folders.go
├── go.mod
├── go.sum
├── kms.go
├── models.go
├── packages
├── api
│ ├── auth
│ │ ├── aws_iam_auth_login.go
│ │ ├── azure_auth_login.go
│ │ ├── gcp_id_token_auth_login.go
│ │ ├── jwt_auth_login.go
│ │ ├── kubernetes_auth_login.go
│ │ ├── models.go
│ │ ├── oidc_auth_login.go
│ │ ├── renew_access_token.go
│ │ ├── revoke_access_token.go
│ │ └── universal_auth_login.go
│ ├── dynamic_secrets
│ │ ├── create_lease.go
│ │ ├── delete_lease.go
│ │ ├── get_lease_by_id.go
│ │ ├── get_secret_by_name.go
│ │ ├── list_lease.go
│ │ ├── list_secrets.go
│ │ ├── models.go
│ │ └── renew_lease.go
│ ├── folders
│ │ ├── create_folder.go
│ │ ├── delete_folder.go
│ │ ├── list_folders.go
│ │ ├── models.go
│ │ └── update_folder.go
│ ├── kms
│ │ ├── create_key.go
│ │ ├── decrypt_data.go
│ │ ├── delete_key.go
│ │ ├── encrypt_data.go
│ │ ├── get_key_by_name.go
│ │ ├── get_public_key.go
│ │ ├── get_signing_algorithms.go
│ │ ├── models.go
│ │ ├── sign_data.go
│ │ └── verify_data.go
│ ├── secrets
│ │ ├── bulk_create_secrets.go
│ │ ├── create_secret.go
│ │ ├── delete_secret.go
│ │ ├── list_secrets.go
│ │ ├── models.go
│ │ ├── retrieve_secret.go
│ │ └── update_secret.go
│ └── ssh
│ │ ├── add_ssh_host.go
│ │ ├── get_ssh_host_host_ca_pk.go
│ │ ├── get_ssh_host_user_ca_pk.go
│ │ ├── get_ssh_hosts.go
│ │ ├── issue_ssh_creds.go
│ │ ├── issue_ssh_host_host_cert.go
│ │ ├── issue_ssh_host_user_cert.go
│ │ ├── models.go
│ │ └── sign_ssh_public_key.go
├── errors
│ ├── api.go
│ └── request.go
├── models
│ ├── auth.go
│ ├── dynamic_secrets.go
│ ├── folders.go
│ └── secrets.go
└── util
│ ├── auth.go
│ ├── constants.go
│ └── helper.go
├── resources
└── logo.svg
├── secrets.go
├── ssh.go
└── test
├── aws_auth_test.go
├── kubernetes_auth_test.go
├── secrets_batch_create_test.go
├── ssh_test.go
└── universal_auth_test.go
/.github/workflows/build-lint.yml:
--------------------------------------------------------------------------------
1 | name: Build and Lint
2 |
3 | # Basic concurrency per branch
4 | concurrency:
5 | group: ${{ github.workflow }}-${{ github.ref }}
6 | cancel-in-progress: true
7 |
8 | on:
9 | pull_request:
10 | types: [opened, synchronize]
11 |
12 | jobs:
13 | build:
14 | name: Build
15 | runs-on: ubuntu-latest
16 | timeout-minutes: 5
17 | steps:
18 | - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
19 | - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
20 | with:
21 | go-version-file: "go.mod"
22 | cache: false
23 | - run: go mod download
24 | - run: go build -v .
25 | - name: Run linters
26 | uses: golangci/golangci-lint-action@5f1fec7010f6ae3b84ea4f7b2129beb8639b564f # v3.5.0
27 | with:
28 | version: latest
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # If you prefer the allow list template instead of the deny list, see community template:
2 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
3 | #
4 | # Binaries for programs and plugins
5 | *.exe
6 | *.exe~
7 | *.dll
8 | *.so
9 | *.dylib
10 |
11 | # Test binary, built with `go test -c`
12 | *.test
13 |
14 | # Output of the go coverage tool, specifically when used with LiteIDE
15 | *.out
16 |
17 | # Dependency directories (remove the comment below to include it)
18 | # vendor/
19 |
20 | # Go workspace file
21 | go.work
22 | go.work.sum
23 | .DS_Store
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2024, Infisical Inc
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Infisical Go SDK
6 |
7 |
14 |
15 |
32 |
33 | ## Introduction
34 |
35 | **[Infisical](https://infisical.com)** is the open source secret management platform that teams use to centralize their secrets like API keys, database credentials, and configurations.
36 |
37 | The Infisical Go SDK provides a robust and efficient way for Go developers to integrate Infisical's secret management capabilities into their applications. With our SDK, you can seamlessly retrieve, update, delete, and manage your application's secrets. The SDK offers a simple API, making it easy to integrate Infisical's core features into your Go projects with minimal effort. Whether you are building microservices, cloud-native applications, or any other Go-based systems.
38 |
39 | For detailed documentation on how to get started with the Infisical Go SDK, check out our [SDK Docs](https://infisical.com/docs/sdks/languages/go).
40 |
41 |
42 | ## Security
43 |
44 | Please do not file GitHub issues or post on our public forum for security vulnerabilities, as they are public!
45 |
46 | Infisical takes security issues very seriously. If you have any concerns about Infisical or believe you have uncovered a vulnerability, please get in touch via the e-mail address security@infisical.com. In the message, try to provide a description of the issue and ideally a way of reproducing it. The security team will get back to you as soon as possible.
47 |
48 | Note that this security address should be used only for undisclosed vulnerabilities. Please report any security problems to us before disclosing it publicly.
49 |
50 |
51 | ## Contributing
52 |
53 | Whether it's big or small, we love contributions. Check out our guide to see how to [get started](https://infisical.com/docs/contributing/getting-started).
54 |
55 | Not sure where to get started? Join our Slack , and ask us any questions there.
56 |
--------------------------------------------------------------------------------
/auth.go:
--------------------------------------------------------------------------------
1 | package infisical
2 |
3 | import (
4 | "context"
5 | "crypto/sha256"
6 | "encoding/base64"
7 | "encoding/json"
8 | "errors"
9 | "fmt"
10 | "net/http"
11 | "os"
12 | "strings"
13 | "time"
14 |
15 | api "github.com/infisical/go-sdk/packages/api/auth"
16 | "github.com/infisical/go-sdk/packages/models"
17 | "github.com/infisical/go-sdk/packages/util"
18 |
19 | v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
20 | )
21 |
22 | type KubernetesAuthLoginOptions struct {
23 | IdentityID string
24 | ServiceAccountTokenPath string
25 | }
26 |
27 | // func epochTime() time.Time { return time.Unix(0, 0) }
28 |
29 | type AuthInterface interface {
30 | SetAccessToken(accessToken string)
31 | GetAccessToken() string
32 | UniversalAuthLogin(clientID string, clientSecret string) (credential MachineIdentityCredential, err error)
33 | JwtAuthLogin(identityID string, jwt string) (credential MachineIdentityCredential, err error)
34 | KubernetesAuthLogin(identityID string, serviceAccountTokenPath string) (credential MachineIdentityCredential, err error)
35 | KubernetesRawServiceAccountTokenLogin(identityID string, serviceAccountToken string) (credential MachineIdentityCredential, err error)
36 | AzureAuthLogin(identityID string, resource string) (credential MachineIdentityCredential, err error)
37 | GcpIdTokenAuthLogin(identityID string) (credential MachineIdentityCredential, err error)
38 | GcpIamAuthLogin(identityID string, serviceAccountKeyFilePath string) (credential MachineIdentityCredential, err error)
39 | AwsIamAuthLogin(identityId string) (credential MachineIdentityCredential, err error)
40 | OidcAuthLogin(identityId string, jwt string) (credential MachineIdentityCredential, err error)
41 | RevokeAccessToken() error
42 | }
43 |
44 | type Auth struct {
45 | client *InfisicalClient
46 | }
47 |
48 | func (a *Auth) SetAccessToken(accessToken string) {
49 | a.client.setPlainAccessToken(accessToken)
50 | }
51 |
52 | func (a *Auth) GetAccessToken() string {
53 | // case: user has set an access token manually, so we get it directly from the credential
54 | if a.client.authMethod == util.ACCESS_TOKEN {
55 | if parsedCreds, ok := a.client.credential.(models.AccessTokenCredential); ok {
56 | return parsedCreds.AccessToken
57 | }
58 | return ""
59 | }
60 | return a.client.tokenDetails.AccessToken
61 | }
62 |
63 | func (a *Auth) RevokeAccessToken() error {
64 | if a.client.tokenDetails.AccessToken == "" {
65 | return errors.New("sdk client is not authenticated, cannot revoke access token")
66 | }
67 |
68 | _, err := api.CallRevokeAccessToken(a.client.httpClient, api.RevokeAccessTokenRequest{
69 | AccessToken: a.client.tokenDetails.AccessToken,
70 | })
71 |
72 | if err != nil {
73 | return err
74 | }
75 | a.client.clearAccessToken()
76 |
77 | return nil
78 | }
79 | func (a *Auth) UniversalAuthLogin(clientID string, clientSecret string) (credential MachineIdentityCredential, err error) {
80 |
81 | if clientID == "" {
82 | clientID = os.Getenv(util.INFISICAL_UNIVERSAL_AUTH_CLIENT_ID_ENV_NAME)
83 | }
84 | if clientSecret == "" {
85 | clientSecret = os.Getenv(util.INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET_ENV_NAME)
86 | }
87 |
88 | credential, err = api.CallUniversalAuthLogin(a.client.httpClient, api.UniversalAuthLoginRequest{
89 | ClientID: clientID,
90 | ClientSecret: clientSecret,
91 | })
92 |
93 | if err != nil {
94 | return MachineIdentityCredential{}, err
95 | }
96 |
97 | a.client.setAccessToken(
98 | credential,
99 | models.UniversalAuthCredential{ClientID: clientID, ClientSecret: clientSecret},
100 | util.UNIVERSAL_AUTH,
101 | )
102 | return credential, nil
103 |
104 | }
105 |
106 | func (a *Auth) KubernetesAuthLogin(identityID string, serviceAccountTokenPath string) (credential MachineIdentityCredential, err error) {
107 |
108 | if serviceAccountTokenPath == "" {
109 | serviceAccountTokenPath = os.Getenv(util.DEFAULT_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH)
110 | }
111 | if identityID == "" {
112 | identityID = os.Getenv(util.INFISICAL_KUBERNETES_IDENTITY_ID_ENV_NAME)
113 | }
114 |
115 | serviceAccountToken, serviceAccountTokenErr := util.GetKubernetesServiceAccountToken(serviceAccountTokenPath)
116 |
117 | if serviceAccountTokenErr != nil {
118 | return MachineIdentityCredential{}, serviceAccountTokenErr
119 | }
120 |
121 | credential, err = api.CallKubernetesAuthLogin(a.client.httpClient, api.KubernetesAuthLoginRequest{
122 | IdentityID: identityID,
123 | JWT: serviceAccountToken,
124 | })
125 |
126 | if err != nil {
127 | return MachineIdentityCredential{}, err
128 | }
129 |
130 | a.client.setAccessToken(
131 | credential,
132 | models.KubernetesCredential{IdentityID: identityID, ServiceAccountToken: serviceAccountToken},
133 | util.KUBERNETES,
134 | )
135 |
136 | return credential, nil
137 |
138 | }
139 |
140 | func (a *Auth) KubernetesRawServiceAccountTokenLogin(identityID string, serviceAccountToken string) (credential MachineIdentityCredential, err error) {
141 |
142 | if identityID == "" {
143 | identityID = os.Getenv(util.INFISICAL_KUBERNETES_IDENTITY_ID_ENV_NAME)
144 | }
145 |
146 | credential, err = api.CallKubernetesAuthLogin(a.client.httpClient, api.KubernetesAuthLoginRequest{
147 | IdentityID: identityID,
148 | JWT: serviceAccountToken,
149 | })
150 |
151 | if err != nil {
152 | return MachineIdentityCredential{}, err
153 | }
154 |
155 | a.client.setAccessToken(
156 | credential,
157 | models.KubernetesCredential{IdentityID: identityID, ServiceAccountToken: serviceAccountToken},
158 | util.KUBERNETES,
159 | )
160 | return credential, nil
161 | }
162 |
163 | func (a *Auth) AzureAuthLogin(identityID string, resource string) (credential MachineIdentityCredential, err error) {
164 | if identityID == "" {
165 | identityID = os.Getenv(util.INFISICAL_AZURE_AUTH_IDENTITY_ID_ENV_NAME)
166 | }
167 |
168 | jwt, jwtError := util.GetAzureMetadataToken(a.client.httpClient, resource)
169 |
170 | if jwtError != nil {
171 | return MachineIdentityCredential{}, jwtError
172 | }
173 |
174 | credential, err = api.CallAzureAuthLogin(a.client.httpClient, api.AzureAuthLoginRequest{
175 | IdentityID: identityID,
176 | JWT: jwt,
177 | })
178 |
179 | if err != nil {
180 | return MachineIdentityCredential{}, err
181 | }
182 |
183 | a.client.setAccessToken(
184 | credential,
185 | models.AzureCredential{IdentityID: identityID, Resource: resource},
186 | util.AZURE,
187 | )
188 | return credential, nil
189 | }
190 |
191 | func (a *Auth) GcpIdTokenAuthLogin(identityID string) (credential MachineIdentityCredential, err error) {
192 | if identityID == "" {
193 | identityID = os.Getenv(util.INFISICAL_GCP_AUTH_IDENTITY_ID_ENV_NAME)
194 | }
195 |
196 | jwt, jwtError := util.GetGCPMetadataToken(a.client.httpClient, identityID)
197 |
198 | if jwtError != nil {
199 | return MachineIdentityCredential{}, jwtError
200 | }
201 |
202 | credential, err = api.CallGCPAuthLogin(a.client.httpClient, api.GCPAuthLoginRequest{
203 | IdentityID: identityID,
204 | JWT: jwt,
205 | })
206 |
207 | if err != nil {
208 | return MachineIdentityCredential{}, err
209 | }
210 |
211 | a.client.setAccessToken(
212 | credential,
213 | models.GCPIDTokenCredential{IdentityID: identityID},
214 | util.GCP_ID_TOKEN,
215 | )
216 | return credential, nil
217 | }
218 |
219 | func (a *Auth) GcpIamAuthLogin(identityID string, serviceAccountKeyFilePath string) (credential MachineIdentityCredential, err error) {
220 | if identityID == "" {
221 | identityID = os.Getenv(util.INFISICAL_GCP_AUTH_IDENTITY_ID_ENV_NAME)
222 | }
223 | if serviceAccountKeyFilePath == "" {
224 | serviceAccountKeyFilePath = os.Getenv(util.INFISICAL_GCP_IAM_SERVICE_ACCOUNT_KEY_FILE_PATH_ENV_NAME)
225 | }
226 |
227 | jwt, jwtError := util.GetGCPIamServiceAccountToken(identityID, serviceAccountKeyFilePath)
228 |
229 | if jwtError != nil {
230 | return MachineIdentityCredential{}, jwtError
231 | }
232 |
233 | credential, err = api.CallGCPAuthLogin(a.client.httpClient, api.GCPAuthLoginRequest{
234 | IdentityID: identityID,
235 | JWT: jwt,
236 | })
237 |
238 | if err != nil {
239 | return MachineIdentityCredential{}, err
240 | }
241 |
242 | a.client.setAccessToken(
243 | credential,
244 | models.GCPIAMCredential{IdentityID: identityID, ServiceAccountKeyFilePath: serviceAccountKeyFilePath},
245 | util.GCP_IAM,
246 | )
247 | return credential, nil
248 | }
249 |
250 | func (a *Auth) AwsIamAuthLogin(identityId string) (credential MachineIdentityCredential, err error) {
251 |
252 | if identityId == "" {
253 | identityId = os.Getenv(util.INFISICAL_AWS_IAM_AUTH_IDENTITY_ID_ENV_NAME)
254 | }
255 |
256 | awsCredentials, awsRegion, err := util.RetrieveAwsCredentials()
257 | if err != nil {
258 | return MachineIdentityCredential{}, err
259 | }
260 |
261 | // Prepare request for signing
262 | iamRequestURL := fmt.Sprintf("https://sts.%s.amazonaws.com/", awsRegion)
263 | iamRequestBody := "Action=GetCallerIdentity&Version=2011-06-15"
264 |
265 | req, err := http.NewRequest(http.MethodPost, iamRequestURL, strings.NewReader(iamRequestBody))
266 | if err != nil {
267 | return MachineIdentityCredential{}, fmt.Errorf("error creating HTTP request: %v", err)
268 | }
269 |
270 | currentTime := time.Now().UTC()
271 | req.Header.Add("X-Amz-Date", currentTime.Format("20060102T150405Z"))
272 |
273 | hashGenerator := sha256.New()
274 | hashGenerator.Write([]byte(iamRequestBody))
275 | payloadHash := fmt.Sprintf("%x", hashGenerator.Sum(nil))
276 |
277 | signer := v4.NewSigner()
278 | err = signer.SignHTTP(context.TODO(), awsCredentials, req, payloadHash, "sts", awsRegion, time.Now())
279 |
280 | if err != nil {
281 | return MachineIdentityCredential{}, fmt.Errorf("error signing request: %v", err)
282 | }
283 |
284 | var realHeaders map[string]string = make(map[string]string)
285 | for name, values := range req.Header {
286 | if strings.ToLower(name) == "content-length" {
287 | continue
288 | }
289 | realHeaders[name] = values[0]
290 | }
291 | realHeaders["Host"] = fmt.Sprintf("sts.%s.amazonaws.com", awsRegion)
292 | realHeaders["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8"
293 | realHeaders["Content-Length"] = fmt.Sprintf("%d", len(iamRequestBody))
294 |
295 | // convert the headers to a json marshalled string
296 | jsonStringHeaders, err := json.Marshal(realHeaders)
297 |
298 | if err != nil {
299 | return MachineIdentityCredential{}, fmt.Errorf("error marshalling headers: %v", err)
300 | }
301 |
302 | credential, tokenErr := api.CallAWSIamAuthLogin(a.client.httpClient, api.AwsIamAuthLoginRequest{
303 | HTTPRequestMethod: req.Method,
304 | // Encoding is intended, we decode it on severside, and I know everything happening on the server is being done correctly. So it's something broken in this code somewhere.
305 | IamRequestBody: base64.StdEncoding.EncodeToString([]byte(iamRequestBody)),
306 | IamRequestHeaders: base64.StdEncoding.EncodeToString(jsonStringHeaders),
307 | IdentityId: identityId,
308 | })
309 |
310 | if tokenErr != nil {
311 | return MachineIdentityCredential{}, tokenErr
312 | }
313 |
314 | a.client.setAccessToken(
315 | credential,
316 | models.AWSIAMCredential{IdentityID: identityId},
317 | util.AWS_IAM,
318 | )
319 | return credential, nil
320 | }
321 |
322 | func (a *Auth) OidcAuthLogin(identityId string, jwt string) (credential MachineIdentityCredential, err error) {
323 | if identityId == "" {
324 | identityId = os.Getenv(util.INFISICAL_OIDC_AUTH_IDENTITY_ID_ENV_NAME)
325 | }
326 |
327 | credential, err = api.CallOidcAuthLogin(a.client.httpClient, api.OidcAuthLoginRequest{
328 | IdentityID: identityId,
329 | JWT: jwt,
330 | })
331 |
332 | if err != nil {
333 | return MachineIdentityCredential{}, err
334 | }
335 |
336 | a.client.setAccessToken(
337 | credential,
338 | models.OIDCCredential{IdentityID: identityId},
339 | util.OIDC_AUTH,
340 | )
341 | return credential, nil
342 |
343 | }
344 |
345 | func (a *Auth) JwtAuthLogin(identityID string, jwt string) (credential MachineIdentityCredential, err error) {
346 | credential, err = api.CallJwtAuthLogin(a.client.httpClient, api.JwtAuthLoginRequest{
347 | IdentityID: identityID,
348 | JWT: jwt,
349 | })
350 |
351 | if err != nil {
352 | return MachineIdentityCredential{}, err
353 | }
354 |
355 | a.client.setAccessToken(
356 | credential,
357 | models.JWTCredential{IdentityID: identityID, JWT: jwt},
358 | util.JWT_AUTH,
359 | )
360 | return credential, nil
361 | }
362 |
363 | func NewAuth(client *InfisicalClient) AuthInterface {
364 | return &Auth{client: client}
365 | }
366 |
--------------------------------------------------------------------------------
/bin/golangci-lint:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Infisical/go-sdk/b0c7741ec9fa28c858a8b3a9702fd17933c0a713/bin/golangci-lint
--------------------------------------------------------------------------------
/client.go:
--------------------------------------------------------------------------------
1 | package infisical
2 |
3 | import (
4 | "context"
5 | "crypto/tls"
6 | "crypto/x509"
7 | "errors"
8 | "fmt"
9 | "math"
10 | "math/rand"
11 | "net"
12 | "reflect"
13 | "strconv"
14 | "strings"
15 | "sync"
16 | "time"
17 |
18 | "github.com/go-resty/resty/v2"
19 | "github.com/hashicorp/golang-lru/v2/expirable"
20 | api "github.com/infisical/go-sdk/packages/api/auth"
21 | "github.com/infisical/go-sdk/packages/models"
22 | "github.com/infisical/go-sdk/packages/util"
23 | )
24 |
25 | type InfisicalClient struct {
26 | authMethod util.AuthMethod
27 | credential interface{}
28 | tokenDetails MachineIdentityCredential
29 | lastFetchedTime time.Time
30 | firstFetchedTime time.Time
31 |
32 | mu sync.RWMutex
33 |
34 | cache *expirable.LRU[string, interface{}]
35 |
36 | httpClient *resty.Client
37 | config Config
38 |
39 | secrets SecretsInterface
40 | folders FoldersInterface
41 | auth AuthInterface
42 | dynamicSecrets DynamicSecretsInterface
43 | kms KmsInterface
44 | ssh SshInterface
45 | }
46 |
47 | type InfisicalClientInterface interface {
48 | UpdateConfiguration(config Config)
49 | Secrets() SecretsInterface
50 | Folders() FoldersInterface
51 | Auth() AuthInterface
52 | DynamicSecrets() DynamicSecretsInterface
53 | Kms() KmsInterface
54 | Ssh() SshInterface
55 | }
56 |
57 | type Config struct {
58 | SiteUrl string `default:"https://app.infisical.com"`
59 | CaCertificate string
60 | UserAgent string `default:"infisical-go-sdk"` // User-Agent header to be used on requests sent by the SDK. Defaults to `infisical-go-sdk`. Do not modify this unless you have a reason to do so.
61 | AutoTokenRefresh bool `default:"true"` // Wether or not to automatically refresh the auth token after using one of the .Auth() methods. Defaults to `true`.
62 | SilentMode bool `default:"false"` // If enabled, the SDK will not print any warnings to the console.
63 | CacheExpiryInSeconds int // Defines how long certain API responses should be cached in memory, in seconds. When set to a positive value, responses from specific fetch API requests (like secret fetching) will be cached for this duration. Set to 0 to disable caching. Defaults to 0.
64 | CustomHeaders map[string]string
65 | }
66 |
67 | func setDefaults(cfg *Config) {
68 | t := reflect.TypeOf(*cfg) // we need to dereference the pointer to get the struct type
69 | v := reflect.ValueOf(cfg).Elem()
70 |
71 | for i := 0; i < t.NumField(); i++ {
72 | field := t.Field(i)
73 | defaultVal := field.Tag.Get("default")
74 | if defaultVal == "" {
75 | continue
76 | }
77 |
78 | switch field.Type.Kind() {
79 | case reflect.Int:
80 | if v.Field(i).Int() == 0 {
81 | val, _ := strconv.Atoi(defaultVal)
82 | v.Field(i).SetInt(int64(val))
83 | }
84 | case reflect.String:
85 | if v.Field(i).String() == "" {
86 | v.Field(i).SetString(defaultVal)
87 | }
88 | case reflect.Bool:
89 | if !v.Field(i).Bool() {
90 | val, _ := strconv.ParseBool(defaultVal)
91 | v.Field(i).SetBool(val)
92 | }
93 | }
94 | }
95 | }
96 |
97 | func (c *InfisicalClient) setAccessToken(tokenDetails MachineIdentityCredential, credential interface{}, authMethod util.AuthMethod) {
98 | c.mu.Lock()
99 | defer c.mu.Unlock()
100 |
101 | c.tokenDetails = tokenDetails
102 | c.lastFetchedTime = time.Now()
103 |
104 | if c.authMethod != authMethod || c.firstFetchedTime.IsZero() {
105 | c.firstFetchedTime = time.Now()
106 | c.authMethod = authMethod
107 | }
108 |
109 | c.credential = credential
110 | c.httpClient.SetAuthScheme("Bearer")
111 | c.httpClient.SetAuthToken(c.tokenDetails.AccessToken)
112 | }
113 |
114 | func (c *InfisicalClient) clearAccessToken() {
115 | c.mu.Lock()
116 | defer c.mu.Unlock()
117 |
118 | c.tokenDetails = MachineIdentityCredential{}
119 | c.authMethod = ""
120 | c.httpClient.SetAuthScheme("")
121 | c.httpClient.SetAuthToken("")
122 | }
123 | func (c *InfisicalClient) setPlainAccessToken(accessToken string) {
124 | c.mu.Lock()
125 | defer c.mu.Unlock()
126 |
127 | c.authMethod = util.ACCESS_TOKEN
128 | c.httpClient.SetAuthScheme("Bearer")
129 | c.httpClient.SetAuthToken(accessToken)
130 |
131 | c.credential = models.AccessTokenCredential{AccessToken: accessToken}
132 | }
133 |
134 | func NewInfisicalClient(context context.Context, config Config) InfisicalClientInterface {
135 | client := &InfisicalClient{}
136 | setDefaults(&config)
137 | client.UpdateConfiguration(config) // set httpClient and config
138 |
139 | // add interfaces here
140 | client.secrets = NewSecrets(client)
141 | client.folders = NewFolders(client)
142 | client.auth = NewAuth(client)
143 | client.dynamicSecrets = NewDynamicSecrets(client)
144 | client.kms = NewKms(client)
145 | client.ssh = NewSsh(client)
146 | if config.CacheExpiryInSeconds != 0 {
147 | // hard limit set at 1000 cache items until forced eviction
148 | client.cache = expirable.NewLRU[string, interface{}](1000, nil, time.Second*time.Duration(config.CacheExpiryInSeconds))
149 | }
150 |
151 | if config.AutoTokenRefresh {
152 | go client.handleTokenLifeCycle(context)
153 | }
154 |
155 | return client
156 | }
157 |
158 | func (c *InfisicalClient) UpdateConfiguration(config Config) {
159 | c.mu.Lock()
160 | defer c.mu.Unlock()
161 |
162 | setDefaults(&config)
163 | config.SiteUrl = util.AppendAPIEndpoint(config.SiteUrl)
164 | c.config = config
165 |
166 | if c.httpClient == nil {
167 | c.httpClient = resty.New().
168 | SetHeader("User-Agent", config.UserAgent).
169 | SetBaseURL(config.SiteUrl)
170 |
171 | c.httpClient.SetRetryCount(3).
172 | SetRetryWaitTime(1 * time.Second).
173 | SetRetryMaxWaitTime(30 * time.Second).
174 | SetRetryAfter(func(c *resty.Client, r *resty.Response) (time.Duration, error) {
175 |
176 | attempt := r.Request.Attempt + 1
177 | if attempt <= 0 {
178 | attempt = 1
179 | }
180 | waitTime := math.Min(float64(c.RetryWaitTime)*math.Pow(2, float64(attempt-1)), float64(c.RetryMaxWaitTime))
181 |
182 | // Add jitter of +/-20%
183 | jitterFactor := 0.8 + (rand.Float64() * 0.4)
184 | waitTime = waitTime * jitterFactor
185 |
186 | waitDuration := time.Duration(waitTime)
187 | return waitDuration, nil
188 | }).
189 | AddRetryCondition(func(r *resty.Response, err error) bool {
190 | // don't retry if there's no error or it's a timeout
191 | if err == nil || errors.Is(err, context.DeadlineExceeded) {
192 | return false
193 | }
194 |
195 | errMsg := err.Error()
196 |
197 | networkErrors := []string{
198 | "connection refused",
199 | "connection reset",
200 | "network",
201 | "connection",
202 | "no such host",
203 | "i/o timeout",
204 | "dial tcp",
205 | "broken pipe",
206 | "wsaetimeout",
207 | "wsaeconnreset",
208 | "econnreset",
209 | "econnrefused",
210 | "ehostunreach",
211 | "enetunreach",
212 | }
213 |
214 | isConditionMet := false
215 |
216 | var netErr net.Error
217 | if errors.As(err, &netErr) {
218 | return true
219 | }
220 |
221 | for _, netErr := range networkErrors {
222 | if strings.Contains(strings.ToLower(errMsg), netErr) {
223 | isConditionMet = true
224 | }
225 | }
226 |
227 | return isConditionMet
228 |
229 | })
230 |
231 | } else {
232 | c.httpClient.
233 | SetHeader("User-Agent", config.UserAgent).
234 | SetBaseURL(config.SiteUrl)
235 | }
236 |
237 | if len(config.CustomHeaders) > 0 {
238 | c.httpClient.SetHeaders(config.CustomHeaders)
239 | }
240 |
241 | if config.CaCertificate != "" {
242 | caCertPool, err := x509.SystemCertPool()
243 | if err != nil && !config.SilentMode {
244 | util.PrintWarning(fmt.Sprintf("failed to load system root CA pool: %v", err))
245 | }
246 |
247 | if ok := caCertPool.AppendCertsFromPEM([]byte(config.CaCertificate)); !ok && !config.SilentMode {
248 | util.PrintWarning("failed to append CA certificate")
249 | }
250 |
251 | tlsConfig := &tls.Config{
252 | RootCAs: caCertPool,
253 | }
254 |
255 | c.httpClient.SetTLSClientConfig(tlsConfig)
256 | }
257 | }
258 |
259 | func (c *InfisicalClient) Secrets() SecretsInterface {
260 | return c.secrets
261 | }
262 |
263 | func (c *InfisicalClient) Folders() FoldersInterface {
264 | return c.folders
265 | }
266 |
267 | func (c *InfisicalClient) Auth() AuthInterface {
268 | return c.auth
269 | }
270 |
271 | func (c *InfisicalClient) DynamicSecrets() DynamicSecretsInterface {
272 | return c.dynamicSecrets
273 | }
274 |
275 | func (c *InfisicalClient) Kms() KmsInterface {
276 | return c.kms
277 | }
278 |
279 | func (c *InfisicalClient) Ssh() SshInterface {
280 | return c.ssh
281 | }
282 |
283 | func (c *InfisicalClient) handleTokenLifeCycle(context context.Context) {
284 | var warningPrinted = false
285 | authStrategies := map[util.AuthMethod]func(cred interface{}) (credential MachineIdentityCredential, err error){
286 | util.UNIVERSAL_AUTH: func(cred interface{}) (credential MachineIdentityCredential, err error) {
287 | if parsedCreds, ok := cred.(models.UniversalAuthCredential); ok {
288 | return c.auth.UniversalAuthLogin(parsedCreds.ClientID, parsedCreds.ClientSecret)
289 | }
290 | return MachineIdentityCredential{}, fmt.Errorf("failed to parse UniversalAuthCredential")
291 | },
292 | util.KUBERNETES: func(cred interface{}) (credential MachineIdentityCredential, err error) {
293 | if parsedCreds, ok := cred.(models.KubernetesCredential); ok {
294 | return c.auth.KubernetesRawServiceAccountTokenLogin(parsedCreds.IdentityID, parsedCreds.ServiceAccountToken)
295 | }
296 | return MachineIdentityCredential{}, fmt.Errorf("failed to parse KubernetesAuthCredential")
297 | },
298 | util.AZURE: func(cred interface{}) (credential MachineIdentityCredential, err error) {
299 | if parsedCreds, ok := cred.(models.AzureCredential); ok {
300 | return c.auth.AzureAuthLogin(parsedCreds.IdentityID, parsedCreds.Resource)
301 | }
302 | return MachineIdentityCredential{}, fmt.Errorf("failed to parse AzureAuthCredential")
303 | },
304 | util.GCP_ID_TOKEN: func(cred interface{}) (credential MachineIdentityCredential, err error) {
305 | if parsedCreds, ok := cred.(models.GCPIDTokenCredential); ok {
306 | return c.auth.GcpIdTokenAuthLogin(parsedCreds.IdentityID)
307 | }
308 |
309 | return MachineIdentityCredential{}, fmt.Errorf("failed to parse GCPIDTokenCredential")
310 | },
311 | util.GCP_IAM: func(cred interface{}) (credential MachineIdentityCredential, err error) {
312 | if parsedCreds, ok := cred.(models.GCPIAMCredential); ok {
313 | return c.auth.GcpIamAuthLogin(parsedCreds.IdentityID, parsedCreds.ServiceAccountKeyFilePath)
314 | }
315 | return MachineIdentityCredential{}, fmt.Errorf("failed to parse GCPIAMCredential")
316 | },
317 | util.AWS_IAM: func(cred interface{}) (credential MachineIdentityCredential, err error) {
318 | if parsedCreds, ok := cred.(models.AWSIAMCredential); ok {
319 | return c.auth.AwsIamAuthLogin(parsedCreds.IdentityID)
320 | }
321 |
322 | return MachineIdentityCredential{}, fmt.Errorf("failed to parse AWSIAMCredential")
323 | },
324 | util.JWT_AUTH: func(cred interface{}) (credential MachineIdentityCredential, err error) {
325 | if parsedCreds, ok := cred.(models.JWTCredential); ok {
326 | return c.auth.JwtAuthLogin(parsedCreds.IdentityID, parsedCreds.JWT)
327 | }
328 | return MachineIdentityCredential{}, fmt.Errorf("failed to parse JWTCredential")
329 | },
330 | }
331 |
332 | const RE_AUTHENTICATION_INTERVAL_BUFFER = 2
333 | const RENEWAL_INTERVAL_BUFFER = 5
334 |
335 | for {
336 | select {
337 | case <-context.Done():
338 | return // The context has been cancelled, clean up and return from the loop to stop the goroutine
339 | default:
340 | {
341 |
342 | c.mu.RLock()
343 | config := c.config
344 | authMethod := c.authMethod
345 | tokenDetails := c.tokenDetails
346 | clientCredential := c.credential
347 | c.mu.RUnlock()
348 |
349 | if config.AutoTokenRefresh && authMethod != "" && authMethod != util.ACCESS_TOKEN {
350 |
351 | if !config.SilentMode && !warningPrinted && tokenDetails.AccessTokenMaxTTL != 0 && tokenDetails.ExpiresIn != 0 {
352 | if tokenDetails.AccessTokenMaxTTL < 60 || tokenDetails.ExpiresIn < 60 {
353 | util.PrintWarning("Machine Identity access token TTL or max TTL is less than 60 seconds. This may cause excessive API calls, and you may be subject to rate-limits.")
354 | }
355 | warningPrinted = true
356 | }
357 |
358 | c.mu.RLock()
359 |
360 | timeNow := time.Now()
361 | timeSinceLastFetchSeconds := timeNow.Sub(c.lastFetchedTime).Seconds()
362 | timeSinceFirstFetchSeconds := timeNow.Sub(c.firstFetchedTime).Seconds()
363 | c.mu.RUnlock()
364 |
365 | if timeSinceFirstFetchSeconds >= float64(tokenDetails.AccessTokenMaxTTL-RE_AUTHENTICATION_INTERVAL_BUFFER) {
366 | newToken, err := authStrategies[c.authMethod](clientCredential)
367 |
368 | if err != nil && !config.SilentMode {
369 | util.PrintWarning(fmt.Sprintf("Failed to re-authenticate: %s\n", err.Error()))
370 | } else {
371 | c.setAccessToken(newToken, c.credential, c.authMethod)
372 | c.mu.Lock()
373 | c.firstFetchedTime = time.Now()
374 | c.mu.Unlock()
375 | }
376 |
377 | } else if timeSinceLastFetchSeconds >= float64(tokenDetails.ExpiresIn-RENEWAL_INTERVAL_BUFFER) {
378 | timeUntilMaxTTL := float64(tokenDetails.AccessTokenMaxTTL) - timeSinceFirstFetchSeconds
379 |
380 | // Case 1: The time until the max TTL is less than the time until the next access token expiry
381 | if timeUntilMaxTTL < float64(tokenDetails.ExpiresIn) {
382 | // If renewing would exceed max TTL, directly re-authenticate
383 | newToken, err := authStrategies[c.authMethod](clientCredential)
384 | if err != nil && !config.SilentMode {
385 | util.PrintWarning(fmt.Sprintf("Failed to re-authenticate: %s\n", err.Error()))
386 | } else {
387 | c.setAccessToken(newToken, c.credential, c.authMethod)
388 | c.mu.Lock()
389 | c.firstFetchedTime = time.Now()
390 | c.mu.Unlock()
391 | }
392 | // Case 2: The time until the max TTL is greater than the time until the next access token expiry
393 | } else {
394 | renewedCredential, err := api.CallRenewAccessToken(c.httpClient, api.RenewAccessTokenRequest{AccessToken: tokenDetails.AccessToken})
395 |
396 | if err != nil {
397 | if !config.SilentMode {
398 | util.PrintWarning(fmt.Sprintf("Failed to renew access token: %s\n\nAttempting to re-authenticate.", err.Error()))
399 | }
400 |
401 | newToken, err := authStrategies[c.authMethod](clientCredential)
402 | if err != nil && !config.SilentMode {
403 | util.PrintWarning(fmt.Sprintf("Failed to re-authenticate: %s\n", err.Error()))
404 | } else {
405 | c.setAccessToken(newToken, c.credential, c.authMethod)
406 | c.mu.Lock()
407 | c.firstFetchedTime = time.Now()
408 | c.mu.Unlock()
409 | }
410 | } else {
411 | c.setAccessToken(renewedCredential, clientCredential, authMethod)
412 | }
413 | }
414 | }
415 |
416 | c.mu.RLock()
417 | nextAccessTokenExpiresInTime := c.lastFetchedTime.Add(time.Duration(tokenDetails.ExpiresIn*int64(time.Second)) - (5 * time.Second))
418 | accessTokenMaxTTLExpiresInTime := c.firstFetchedTime.Add(time.Duration(tokenDetails.AccessTokenMaxTTL*int64(time.Second)) - (5 * time.Second))
419 | expiresIn := time.Duration(c.tokenDetails.ExpiresIn * int64(time.Second))
420 | c.mu.RUnlock()
421 |
422 | if nextAccessTokenExpiresInTime.After(accessTokenMaxTTLExpiresInTime) {
423 | // Calculate the sleep time
424 | sleepTime := expiresIn - nextAccessTokenExpiresInTime.Sub(accessTokenMaxTTLExpiresInTime)
425 |
426 | // Ensure we sleep for at least 1 second
427 | if sleepTime < 1*time.Second {
428 | sleepTime = time.Second * 1
429 | }
430 |
431 | if err := util.SleepWithContext(context, sleepTime); err != nil && (err == util.ErrContextCanceled || errors.Is(err, util.ErrContextDeadlineExceeded)) {
432 | return
433 | }
434 |
435 | } else {
436 | sleepTime := expiresIn - (5 * time.Second)
437 |
438 | if sleepTime < time.Second {
439 | sleepTime = time.Millisecond * 500
440 | }
441 |
442 | if err := util.SleepWithContext(context, sleepTime); err != nil && (err == util.ErrContextCanceled || errors.Is(err, util.ErrContextDeadlineExceeded)) {
443 | return
444 | }
445 | }
446 | } else {
447 | if err := util.SleepWithContext(context, 1*time.Second); err != nil && (err == util.ErrContextCanceled || errors.Is(err, util.ErrContextDeadlineExceeded)) {
448 | return
449 | }
450 | }
451 | }
452 | }
453 | }
454 | }
455 |
--------------------------------------------------------------------------------
/dynamic_secrets.go:
--------------------------------------------------------------------------------
1 | package infisical
2 |
3 | import (
4 | api "github.com/infisical/go-sdk/packages/api/dynamic_secrets"
5 | "github.com/infisical/go-sdk/packages/models"
6 | )
7 |
8 | type ListDynamicSecretLeasesOptions = api.ListDynamicSecretLeaseV1Request
9 | type CreateDynamicSecretLeaseOptions = api.CreateDynamicSecretLeaseV1Request
10 | type DeleteDynamicSecretLeaseOptions = api.DeleteDynamicSecretLeaseV1Request
11 | type GetDynamicSecretLeaseByIdOptions = api.GetDynamicSecretLeaseByIdV1Request
12 | type RenewDynamicSecretLeaseOptions = api.RenewDynamicSecretLeaseV1Request
13 | type ListDynamicSecretsRootCredentialsOptions = api.ListDynamicSecretsV1Request
14 | type GetDynamicSecretRootCredentialByNameOptions = api.GetDynamicSecretByNameV1Request
15 |
16 | type DynamicSecretsInterface interface {
17 | List(options ListDynamicSecretsRootCredentialsOptions) ([]models.DynamicSecret, error)
18 | GetByName(options GetDynamicSecretRootCredentialByNameOptions) (models.DynamicSecret, error)
19 | Leases() DynamicSecretLeaseInterface
20 | }
21 |
22 | type DynamicSecretLeaseInterface interface {
23 | List(options ListDynamicSecretLeasesOptions) ([]models.DynamicSecretLease, error)
24 | Create(options CreateDynamicSecretLeaseOptions) (map[string]any, models.DynamicSecret, models.DynamicSecretLease, error)
25 | GetById(options GetDynamicSecretLeaseByIdOptions) (models.DynamicSecretLeaseWithDynamicSecret, error)
26 | DeleteById(options DeleteDynamicSecretLeaseOptions) (models.DynamicSecretLease, error)
27 | RenewById(options RenewDynamicSecretLeaseOptions) (models.DynamicSecretLease, error)
28 | }
29 |
30 | type DynamicSecrets struct {
31 | client *InfisicalClient
32 | leases DynamicSecretLeaseInterface
33 | }
34 |
35 | func (f *DynamicSecrets) List(options ListDynamicSecretsRootCredentialsOptions) ([]models.DynamicSecret, error) {
36 | res, err := api.CallListDynamicSecretsV1(f.client.httpClient, options)
37 |
38 | if err != nil {
39 | return nil, err
40 | }
41 |
42 | return res.DynamicSecrets, nil
43 | }
44 |
45 | func (f *DynamicSecrets) GetByName(options GetDynamicSecretRootCredentialByNameOptions) (models.DynamicSecret, error) {
46 | res, err := api.CallGetDynamicSecretByNameV1(f.client.httpClient, options)
47 |
48 | if err != nil {
49 | return models.DynamicSecret{}, err
50 | }
51 |
52 | return res.DynamicSecret, nil
53 | }
54 |
55 | func (f *DynamicSecrets) Leases() DynamicSecretLeaseInterface {
56 | return f.leases
57 | }
58 |
59 | type DynamicSecretLeases struct {
60 | client *InfisicalClient
61 | }
62 |
63 | func (f *DynamicSecretLeases) List(options ListDynamicSecretLeasesOptions) ([]models.DynamicSecretLease, error) {
64 | res, err := api.CallListDynamicSecretLeaseV1(f.client.httpClient, options)
65 |
66 | if err != nil {
67 | return nil, err
68 | }
69 |
70 | return res.Leases, nil
71 | }
72 |
73 | func (f *DynamicSecretLeases) Create(options CreateDynamicSecretLeaseOptions) (map[string]any, models.DynamicSecret, models.DynamicSecretLease, error) {
74 | res, err := api.CallCreateDynamicSecretLeaseV1(f.client.httpClient, options)
75 |
76 | if err != nil {
77 | return nil, models.DynamicSecret{}, models.DynamicSecretLease{}, err
78 | }
79 |
80 | return res.Data, res.DynamicSecret, res.Lease, nil
81 | }
82 |
83 | func (f *DynamicSecretLeases) GetById(options GetDynamicSecretLeaseByIdOptions) (models.DynamicSecretLeaseWithDynamicSecret, error) {
84 | res, err := api.CallGetByDynamicSecretByIdLeaseV1(f.client.httpClient, options)
85 |
86 | if err != nil {
87 | return models.DynamicSecretLeaseWithDynamicSecret{}, err
88 | }
89 |
90 | return res.Lease, nil
91 | }
92 |
93 | func (f *DynamicSecretLeases) DeleteById(options DeleteDynamicSecretLeaseOptions) (models.DynamicSecretLease, error) {
94 | res, err := api.CallDeleteDynamicSecretLeaseV1(f.client.httpClient, options)
95 |
96 | if err != nil {
97 | return models.DynamicSecretLease{}, err
98 | }
99 |
100 | return res.Lease, nil
101 | }
102 |
103 | func (f *DynamicSecretLeases) RenewById(options RenewDynamicSecretLeaseOptions) (models.DynamicSecretLease, error) {
104 | res, err := api.CallRenewDynamicSecretLeaseV1(f.client.httpClient, options)
105 |
106 | if err != nil {
107 | return models.DynamicSecretLease{}, err
108 | }
109 |
110 | return res.Lease, nil
111 | }
112 |
113 | func NewDynamicSecrets(client *InfisicalClient) DynamicSecretsInterface {
114 | return &DynamicSecrets{client: client, leases: &DynamicSecretLeases{client: client}}
115 | }
116 |
--------------------------------------------------------------------------------
/folders.go:
--------------------------------------------------------------------------------
1 | package infisical
2 |
3 | import (
4 | api "github.com/infisical/go-sdk/packages/api/folders"
5 | "github.com/infisical/go-sdk/packages/models"
6 | )
7 |
8 | type ListFoldersOptions = api.ListFoldersV1Request
9 | type UpdateFolderOptions = api.UpdateFolderV1Request
10 | type CreateFolderOptions = api.CreateFolderV1Request
11 | type DeleteFolderOptions = api.DeleteFolderV1Request
12 |
13 | type FoldersInterface interface {
14 | List(options ListFoldersOptions) ([]models.Folder, error)
15 | Update(options UpdateFolderOptions) (models.Folder, error)
16 | Create(options CreateFolderOptions) (models.Folder, error)
17 | Delete(options DeleteFolderOptions) (models.Folder, error)
18 | }
19 |
20 | type Folders struct {
21 | client *InfisicalClient
22 | }
23 |
24 | func (f *Folders) List(options ListFoldersOptions) ([]models.Folder, error) {
25 | res, err := api.CallListFoldersV1(f.client.httpClient, options)
26 |
27 | if err != nil {
28 | return nil, err
29 | }
30 |
31 | return res.Folders, nil
32 | }
33 |
34 | func (f *Folders) Update(options UpdateFolderOptions) (models.Folder, error) {
35 | res, err := api.CallUpdateFolderV1(f.client.httpClient, options)
36 |
37 | if err != nil {
38 | return models.Folder{}, err
39 | }
40 |
41 | return res.Folder, nil
42 | }
43 |
44 | func (f *Folders) Create(options CreateFolderOptions) (models.Folder, error) {
45 | res, err := api.CallCreateFolderV1(f.client.httpClient, options)
46 |
47 | if err != nil {
48 | return models.Folder{}, err
49 | }
50 |
51 | return res.Folder, nil
52 | }
53 |
54 | func (f *Folders) Delete(options DeleteFolderOptions) (models.Folder, error) {
55 | res, err := api.CallDeleteFolderV1(f.client.httpClient, options)
56 |
57 | if err != nil {
58 | return models.Folder{}, err
59 | }
60 |
61 | return res.Folder, nil
62 | }
63 |
64 | func NewFolders(client *InfisicalClient) FoldersInterface {
65 | return &Folders{client: client}
66 | }
67 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/infisical/go-sdk
2 |
3 | go 1.21
4 |
5 | require (
6 | cloud.google.com/go/iam v1.1.11
7 | github.com/aws/aws-sdk-go-v2 v1.27.2
8 | github.com/aws/aws-sdk-go-v2/config v1.27.18
9 | github.com/go-resty/resty/v2 v2.13.1
10 | github.com/hashicorp/golang-lru/v2 v2.0.7
11 | google.golang.org/api v0.188.0
12 | )
13 |
14 | require (
15 | cloud.google.com/go/auth v0.7.0 // indirect
16 | cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
17 | cloud.google.com/go/compute/metadata v0.4.0 // indirect
18 | github.com/aws/aws-sdk-go-v2/credentials v1.17.18 // indirect
19 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5 // indirect
20 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9 // indirect
21 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9 // indirect
22 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
23 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect
24 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11 // indirect
25 | github.com/aws/aws-sdk-go-v2/service/sso v1.20.11 // indirect
26 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5 // indirect
27 | github.com/aws/aws-sdk-go-v2/service/sts v1.28.12 // indirect
28 | github.com/aws/smithy-go v1.20.2 // indirect
29 | github.com/felixge/httpsnoop v1.0.4 // indirect
30 | github.com/go-logr/logr v1.4.1 // indirect
31 | github.com/go-logr/stdr v1.2.2 // indirect
32 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
33 | github.com/golang/protobuf v1.5.4 // indirect
34 | github.com/google/s2a-go v0.1.7 // indirect
35 | github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
36 | github.com/googleapis/gax-go/v2 v2.12.5 // indirect
37 | go.opencensus.io v0.24.0 // indirect
38 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
39 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
40 | go.opentelemetry.io/otel v1.24.0 // indirect
41 | go.opentelemetry.io/otel/metric v1.24.0 // indirect
42 | go.opentelemetry.io/otel/trace v1.24.0 // indirect
43 | golang.org/x/crypto v0.31.0 // indirect
44 | golang.org/x/net v0.33.0 // indirect
45 | golang.org/x/oauth2 v0.21.0 // indirect
46 | golang.org/x/sync v0.10.0 // indirect
47 | golang.org/x/sys v0.28.0 // indirect
48 | golang.org/x/text v0.21.0 // indirect
49 | golang.org/x/time v0.5.0 // indirect
50 | google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
51 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b // indirect
52 | google.golang.org/grpc v1.64.1 // indirect
53 | google.golang.org/protobuf v1.34.2 // indirect
54 | )
55 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2 | cloud.google.com/go/auth v0.7.0 h1:kf/x9B3WTbBUHkC+1VS8wwwli9TzhSt0vSTVBmMR8Ts=
3 | cloud.google.com/go/auth v0.7.0/go.mod h1:D+WqdrpcjmiCgWrXmLLxOVq1GACoE36chW6KXoEvuIw=
4 | cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
5 | cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
6 | cloud.google.com/go/compute/metadata v0.4.0 h1:vHzJCWaM4g8XIcm8kopr3XmDA4Gy/lblD3EhhSux05c=
7 | cloud.google.com/go/compute/metadata v0.4.0/go.mod h1:SIQh1Kkb4ZJ8zJ874fqVkslA29PRXuleyj6vOzlbK7M=
8 | cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw=
9 | cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ=
10 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
11 | github.com/aws/aws-sdk-go-v2 v1.27.2 h1:pLsTXqX93rimAOZG2FIYraDQstZaaGVVN4tNw65v0h8=
12 | github.com/aws/aws-sdk-go-v2 v1.27.2/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
13 | github.com/aws/aws-sdk-go-v2/config v1.27.18 h1:wFvAnwOKKe7QAyIxziwSKjmer9JBMH1vzIL6W+fYuKk=
14 | github.com/aws/aws-sdk-go-v2/config v1.27.18/go.mod h1:0xz6cgdX55+kmppvPm2IaKzIXOheGJhAufacPJaXZ7c=
15 | github.com/aws/aws-sdk-go-v2/credentials v1.17.18 h1:D/ALDWqK4JdY3OFgA2thcPO1c9aYTT5STS/CvnkqY1c=
16 | github.com/aws/aws-sdk-go-v2/credentials v1.17.18/go.mod h1:JuitCWq+F5QGUrmMPsk945rop6bB57jdscu+Glozdnc=
17 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5 h1:dDgptDO9dxeFkXy+tEgVkzSClHZje/6JkPW5aZyEvrQ=
18 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5/go.mod h1:gjvE2KBUgUQhcv89jqxrIxH9GaKs1JbZzWejj/DaHGA=
19 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9 h1:cy8ahBJuhtM8GTTSyOkfy6WVPV1IE+SS5/wfXUYuulw=
20 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9/go.mod h1:CZBXGLaJnEZI6EVNcPd7a6B5IC5cA/GkRWtu9fp3S6Y=
21 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9 h1:A4SYk07ef04+vxZToz9LWvAXl9LW0NClpPpMsi31cz0=
22 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9/go.mod h1:5jJcHuwDagxN+ErjQ3PU3ocf6Ylc/p9x+BLO/+X4iXw=
23 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
24 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
25 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs=
26 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg=
27 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11 h1:o4T+fKxA3gTMcluBNZZXE9DNaMkJuUL1O3mffCUjoJo=
28 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11/go.mod h1:84oZdJ+VjuJKs9v1UTC9NaodRZRseOXCTgku+vQJWR8=
29 | github.com/aws/aws-sdk-go-v2/service/sso v1.20.11 h1:gEYM2GSpr4YNWc6hCd5nod4+d4kd9vWIAWrmGuLdlMw=
30 | github.com/aws/aws-sdk-go-v2/service/sso v1.20.11/go.mod h1:gVvwPdPNYehHSP9Rs7q27U1EU+3Or2ZpXvzAYJNh63w=
31 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5 h1:iXjh3uaH3vsVcnyZX7MqCoCfcyxIrVE9iOQruRaWPrQ=
32 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5/go.mod h1:5ZXesEuy/QcO0WUnt+4sDkxhdXRHTu2yG0uCSH8B6os=
33 | github.com/aws/aws-sdk-go-v2/service/sts v1.28.12 h1:M/1u4HBpwLuMtjlxuI2y6HoVLzF5e2mfxHCg7ZVMYmk=
34 | github.com/aws/aws-sdk-go-v2/service/sts v1.28.12/go.mod h1:kcfd+eTdEi/40FIbLq4Hif3XMXnl5b/+t/KTfLt9xIk=
35 | github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q=
36 | github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
37 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
38 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
39 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
40 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
41 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
42 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
43 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
44 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
45 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
46 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
47 | github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
48 | github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
49 | github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
50 | github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
51 | github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
52 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
53 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
54 | github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g=
55 | github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0=
56 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
57 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
58 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
59 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
60 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
61 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
62 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
63 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
64 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
65 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
66 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
67 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
68 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
69 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
70 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
71 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
72 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
73 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
74 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
75 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
76 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
77 | github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
78 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
79 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
80 | github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
81 | github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
82 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
83 | github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
84 | github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
85 | github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA=
86 | github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E=
87 | github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
88 | github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
89 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
90 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
91 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
92 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
93 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
94 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
95 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
96 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
97 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
98 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
99 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
100 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
101 | go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
102 | go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
103 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
104 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
105 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
106 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
107 | go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
108 | go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
109 | go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
110 | go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
111 | go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
112 | go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
113 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
114 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
115 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
116 | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
117 | golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
118 | golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
119 | golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
120 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
121 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
122 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
123 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
124 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
125 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
126 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
127 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
128 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
129 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
130 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
131 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
132 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
133 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
134 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
135 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
136 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
137 | golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
138 | golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
139 | golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
140 | golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
141 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
142 | golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
143 | golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
144 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
145 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
146 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
147 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
148 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
149 | golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
150 | golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
151 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
152 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
153 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
154 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
155 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
156 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
157 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
158 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
159 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
160 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
161 | golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
162 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
163 | golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
164 | golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
165 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
166 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
167 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
168 | golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
169 | golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
170 | golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
171 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
172 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
173 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
174 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
175 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
176 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
177 | golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
178 | golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
179 | golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
180 | golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
181 | golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
182 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
183 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
184 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
185 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
186 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
187 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
188 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
189 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
190 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
191 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
192 | google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw=
193 | google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag=
194 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
195 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
196 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
197 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
198 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
199 | google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
200 | google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
201 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b h1:04+jVzTs2XBnOZcPsLnmrTGqltqJbZQ1Ey26hjYdQQ0=
202 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
203 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
204 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
205 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
206 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
207 | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
208 | google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA=
209 | google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0=
210 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
211 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
212 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
213 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
214 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
215 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
216 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
217 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
218 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
219 | google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
220 | google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
221 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
222 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
223 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
224 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
225 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
226 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
227 |
--------------------------------------------------------------------------------
/kms.go:
--------------------------------------------------------------------------------
1 | package infisical
2 |
3 | import (
4 | "encoding/base64"
5 |
6 | api "github.com/infisical/go-sdk/packages/api/kms"
7 | )
8 |
9 | // Options
10 | type KmsEncryptDataOptions = api.KmsEncryptDataV1Request
11 | type KmsDecryptDataOptions = api.KmsDecryptDataV1Request
12 |
13 | type KmsSignDataOptions = api.KmsSignDataV1Request
14 | type KmsVerifyDataOptions = api.KmsVerifyDataV1Request
15 |
16 | type KmsListSigningAlgorithmsOptions = api.KmsListSigningAlgorithmsV1Request
17 | type KmsGetPublicKeyOptions = api.KmsGetPublicKeyV1Request
18 |
19 | type KmsCreateKeyOptions = api.KmsCreateKeyV1Request
20 | type KmsDeleteKeyOptions = api.KmsDeleteKeyV1Request
21 |
22 | type KmsGetKeyByNameOptions = api.KmsGetKeyByNameV1Request
23 |
24 | // Results
25 | type KmsVerifyDataResult = api.KmsVerifyDataV1Response
26 | type KmsSignDataResult = api.KmsSignDataV1Response
27 |
28 | type KmsCreateKeyResult = api.KmsKey
29 | type KmsDeleteKeyResult = api.KmsKey
30 | type KmsGetKeyResult = api.KmsKey
31 |
32 | type KmsKeysInterface interface {
33 | Create(options KmsCreateKeyOptions) (KmsCreateKeyResult, error)
34 | Delete(options KmsDeleteKeyOptions) (KmsDeleteKeyResult, error)
35 | GetByName(options KmsGetKeyByNameOptions) (KmsGetKeyResult, error)
36 | }
37 |
38 | type KmsSigningInterface interface {
39 | SignData(options KmsSignDataOptions) ([]byte, error)
40 | VerifyData(options KmsVerifyDataOptions) (KmsVerifyDataResult, error)
41 | ListSigningAlgorithms(options KmsListSigningAlgorithmsOptions) ([]string, error)
42 | GetPublicKey(options KmsGetPublicKeyOptions) (string, error)
43 | }
44 |
45 | type KmsInterface interface {
46 | EncryptData(options KmsEncryptDataOptions) (string, error)
47 | DecryptData(options KmsDecryptDataOptions) (string, error)
48 |
49 | Keys() KmsKeysInterface
50 | Signing() KmsSigningInterface
51 | }
52 |
53 | type Kms struct {
54 | client *InfisicalClient
55 | keys *KmsKeys
56 | signing *KmsSigning
57 | }
58 |
59 | type KmsKeys struct {
60 | client *InfisicalClient
61 | }
62 |
63 | type KmsSigning struct {
64 | client *InfisicalClient
65 | }
66 |
67 | func (k *KmsKeys) Create(options KmsCreateKeyOptions) (KmsCreateKeyResult, error) {
68 | res, err := api.CallKmsCreateKeyV1(k.client.httpClient, options)
69 |
70 | if err != nil {
71 | return KmsCreateKeyResult{}, err
72 | }
73 |
74 | return res.Key, nil
75 | }
76 |
77 | func (k *KmsKeys) Delete(options KmsDeleteKeyOptions) (KmsDeleteKeyResult, error) {
78 | res, err := api.CallKmsDeleteKeyV1(k.client.httpClient, options)
79 |
80 | if err != nil {
81 | return KmsDeleteKeyResult{}, err
82 | }
83 |
84 | return res.Key, nil
85 | }
86 |
87 | func (k *KmsKeys) GetByName(options KmsGetKeyByNameOptions) (KmsGetKeyResult, error) {
88 | res, err := api.CallKmsGetKeyByNameV1(k.client.httpClient, options)
89 |
90 | if err != nil {
91 | return KmsGetKeyResult{}, err
92 | }
93 |
94 | return res.Key, nil
95 | }
96 |
97 | func (k *KmsSigning) SignData(options KmsSignDataOptions) ([]byte, error) {
98 | res, err := api.CallKmsSignDataV1(k.client.httpClient, options)
99 |
100 | if err != nil {
101 | return nil, err
102 | }
103 |
104 | return base64.StdEncoding.DecodeString(res.Signature)
105 | }
106 |
107 | func (k *KmsSigning) VerifyData(options KmsVerifyDataOptions) (KmsVerifyDataResult, error) {
108 | res, err := api.CallKmsVerifyDataV1(k.client.httpClient, options)
109 |
110 | if err != nil {
111 | return KmsVerifyDataResult{}, err
112 | }
113 |
114 | return res, nil
115 | }
116 |
117 | func (k *KmsSigning) ListSigningAlgorithms(options KmsListSigningAlgorithmsOptions) ([]string, error) {
118 | res, err := api.CallKmsGetSigningAlgorithmsV1(k.client.httpClient, options)
119 |
120 | if err != nil {
121 | return []string{}, err
122 | }
123 |
124 | return res.SigningAlgorithms, nil
125 | }
126 |
127 | func (k *KmsSigning) GetPublicKey(options KmsGetPublicKeyOptions) (string, error) {
128 | res, err := api.CallKmsGetPublicKeyV1(k.client.httpClient, options)
129 |
130 | if err != nil {
131 | return "", err
132 | }
133 |
134 | return res.PublicKey, nil
135 | }
136 |
137 | func (f *Kms) EncryptData(options KmsEncryptDataOptions) (string, error) {
138 | options.Plaintext = base64.StdEncoding.EncodeToString([]byte(options.Plaintext))
139 | res, err := api.CallKmsEncryptDataV1(f.client.httpClient, options)
140 |
141 | if err != nil {
142 | return "", err
143 | }
144 |
145 | return res.Ciphertext, nil
146 | }
147 |
148 | func (f *Kms) DecryptData(options KmsDecryptDataOptions) (string, error) {
149 | res, err := api.CallKmsDecryptDataV1(f.client.httpClient, options)
150 |
151 | if err != nil {
152 | return "", err
153 | }
154 |
155 | decodedPlaintext, err := base64.StdEncoding.DecodeString(res.Plaintext)
156 | if err != nil {
157 | return "", err
158 | }
159 |
160 | return string(decodedPlaintext), nil
161 | }
162 |
163 | func (f *Kms) Keys() KmsKeysInterface {
164 | return &KmsKeys{client: f.client}
165 | }
166 |
167 | func (f *Kms) Signing() KmsSigningInterface {
168 | return &KmsSigning{client: f.client}
169 | }
170 |
171 | func NewKms(client *InfisicalClient) KmsInterface {
172 | return &Kms{
173 | client: client,
174 | keys: &KmsKeys{client: client},
175 | signing: &KmsSigning{client: client},
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/models.go:
--------------------------------------------------------------------------------
1 | package infisical
2 |
3 | import (
4 | api "github.com/infisical/go-sdk/packages/api/auth"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | "github.com/infisical/go-sdk/packages/models"
7 | )
8 |
9 | type MachineIdentityCredential = api.MachineIdentityAuthLoginResponse
10 |
11 | type Secret = models.Secret
12 | type SecretImport = models.SecretImport
13 |
14 | type APIError = errors.APIError
15 | type RequestError = errors.RequestError
16 |
--------------------------------------------------------------------------------
/packages/api/auth/aws_iam_auth_login.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callAWSIamAuthLoginOperation = "CallAWSIamAuthLogin"
9 |
10 | func CallAWSIamAuthLogin(httpClient *resty.Client, request AwsIamAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
11 | var responseData MachineIdentityAuthLoginResponse
12 |
13 | clonedClient := httpClient.Clone()
14 | clonedClient.SetAuthToken("")
15 | clonedClient.SetAuthScheme("")
16 |
17 | response, err := clonedClient.R().
18 | SetResult(&responseData).
19 | SetBody(request).
20 | Post("/v1/auth/aws-auth/login")
21 |
22 | if err != nil {
23 | return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(callAWSIamAuthLoginOperation, err)
24 | }
25 |
26 | if response.IsError() {
27 | return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(callAWSIamAuthLoginOperation, response)
28 | }
29 |
30 | return responseData, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/auth/azure_auth_login.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const azureAuthLoginOperation = "CallAzureAuthLogin"
9 |
10 | func CallAzureAuthLogin(httpClient *resty.Client, request AzureAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
11 | var responseData MachineIdentityAuthLoginResponse
12 |
13 | clonedClient := httpClient.Clone()
14 | clonedClient.SetAuthToken("")
15 | clonedClient.SetAuthScheme("")
16 |
17 | response, err := clonedClient.R().
18 | SetResult(&responseData).
19 | SetBody(request).
20 | Post("/v1/auth/azure-auth/login")
21 |
22 | if err != nil {
23 | return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(azureAuthLoginOperation, err)
24 | }
25 |
26 | if response.IsError() {
27 | return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(azureAuthLoginOperation, response)
28 | }
29 |
30 | return responseData, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/auth/gcp_id_token_auth_login.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callGCPAuthLoginOperation = "CallGCPAuthLogin"
9 |
10 | func CallGCPAuthLogin(httpClient *resty.Client, request GCPAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
11 | var responseData MachineIdentityAuthLoginResponse
12 |
13 | clonedClient := httpClient.Clone()
14 | clonedClient.SetAuthToken("")
15 | clonedClient.SetAuthScheme("")
16 |
17 | response, err := clonedClient.R().
18 | SetResult(&responseData).
19 | SetBody(request).
20 | Post("/v1/auth/gcp-auth/login")
21 |
22 | if err != nil {
23 | return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(callGCPAuthLoginOperation, err)
24 | }
25 |
26 | if response.IsError() {
27 | return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(callGCPAuthLoginOperation, response)
28 | }
29 |
30 | return responseData, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/auth/jwt_auth_login.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callJwtAuthLoginOperation = "CallJwtAuthLogin"
9 |
10 | func CallJwtAuthLogin(httpClient *resty.Client, request JwtAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
11 | var responseData MachineIdentityAuthLoginResponse
12 |
13 | clonedClient := httpClient.Clone()
14 | clonedClient.SetAuthToken("")
15 | clonedClient.SetAuthScheme("")
16 |
17 | response, err := clonedClient.R().
18 | SetResult(&responseData).
19 | SetBody(request).
20 | Post("/v1/auth/jwt-auth/login")
21 |
22 | if err != nil {
23 | return responseData, errors.NewRequestError(callJwtAuthLoginOperation, err)
24 | }
25 |
26 | if response.IsError() {
27 | return responseData, errors.NewAPIErrorWithResponse(callJwtAuthLoginOperation, response)
28 | }
29 |
30 | return responseData, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/auth/kubernetes_auth_login.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callKubernetesAuthLoginOperation = "CallKubernetesAuthLogin"
9 |
10 | func CallKubernetesAuthLogin(httpClient *resty.Client, request KubernetesAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
11 | var responseData MachineIdentityAuthLoginResponse
12 |
13 | clonedClient := httpClient.Clone()
14 | clonedClient.SetAuthToken("")
15 | clonedClient.SetAuthScheme("")
16 |
17 | response, err := clonedClient.R().
18 | SetResult(&responseData).
19 | SetBody(request).
20 | Post("/v1/auth/kubernetes-auth/login")
21 |
22 | if err != nil {
23 | return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(callKubernetesAuthLoginOperation, err)
24 | }
25 |
26 | if response.IsError() {
27 | return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(callKubernetesAuthLoginOperation, response)
28 | }
29 |
30 | return responseData, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/auth/models.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | // JWT auth:
4 | type JwtAuthLoginRequest struct {
5 | IdentityID string `json:"identityId"`
6 | JWT string `json:"jwt"`
7 | }
8 |
9 | // Revoke access token:
10 | type RevokeAccessTokenRequest struct {
11 | AccessToken string `json:"accessToken"`
12 | }
13 |
14 | type RevokeAccessTokenResponse struct {
15 | Message string `json:"message"`
16 | }
17 |
18 | // Universal auth:
19 | type UniversalAuthLoginRequest struct {
20 | ClientID string `json:"clientId"`
21 | ClientSecret string `json:"clientSecret"`
22 | }
23 |
24 | // Kubernetes auth:
25 | type KubernetesAuthLoginRequest struct {
26 | IdentityID string `json:"identityId"`
27 | JWT string `json:"jwt"`
28 | }
29 |
30 | type AzureAuthLoginRequest struct {
31 | IdentityID string `json:"identityId"`
32 | JWT string `json:"jwt"`
33 | }
34 |
35 | type AwsIamAuthLoginRequest struct {
36 | HTTPRequestMethod string `json:"iamHttpRequestMethod"`
37 | IamRequestBody string `json:"iamRequestBody"`
38 | IamRequestHeaders string `json:"iamRequestHeaders"`
39 | IdentityId string `json:"identityId"`
40 | }
41 |
42 | type GCPAuthLoginRequest struct {
43 | IdentityID string `json:"identityId"`
44 | JWT string `json:"jwt"`
45 | }
46 |
47 | type OidcAuthLoginRequest struct {
48 | IdentityID string `json:"identityId"`
49 | JWT string `json:"jwt"`
50 | }
51 |
52 | type MachineIdentityAuthLoginResponse struct {
53 | AccessToken string `json:"accessToken"`
54 | ExpiresIn int64 `json:"expiresIn"`
55 | AccessTokenMaxTTL int64 `json:"accessTokenMaxTTL"`
56 | TokenType string `json:"tokenType"`
57 | }
58 |
59 | type RenewAccessTokenRequest struct {
60 | AccessToken string `json:"accessToken"`
61 | }
62 |
--------------------------------------------------------------------------------
/packages/api/auth/oidc_auth_login.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callOidcAuthLoginOperation = "CallOidcAuthLogin"
9 |
10 | func CallOidcAuthLogin(httpClient *resty.Client, request OidcAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
11 | var responseData MachineIdentityAuthLoginResponse
12 |
13 | clonedClient := httpClient.Clone()
14 | clonedClient.SetAuthToken("")
15 | clonedClient.SetAuthScheme("")
16 |
17 | response, err := clonedClient.R().
18 | SetResult(&responseData).
19 | SetBody(request).
20 | Post("/v1/auth/oidc-auth/login")
21 |
22 | if err != nil {
23 | return MachineIdentityAuthLoginResponse{}, errors.NewRequestError(callOidcAuthLoginOperation, err)
24 | }
25 |
26 | if response.IsError() {
27 | return MachineIdentityAuthLoginResponse{}, errors.NewAPIErrorWithResponse(callOidcAuthLoginOperation, response)
28 | }
29 |
30 | return responseData, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/auth/renew_access_token.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callRenewAccessToken = "CallRenewAccessToken"
9 |
10 | func CallRenewAccessToken(httpClient *resty.Client, request RenewAccessTokenRequest) (credential MachineIdentityAuthLoginResponse, e error) {
11 | var responseData MachineIdentityAuthLoginResponse
12 |
13 | clonedClient := httpClient.Clone()
14 | clonedClient.SetAuthToken("")
15 | clonedClient.SetAuthScheme("")
16 |
17 | response, err := clonedClient.R().
18 | SetResult(&responseData).
19 | SetBody(request).
20 | Post("/v1/auth/token/renew")
21 |
22 | if err != nil {
23 | return responseData, errors.NewRequestError(callRenewAccessToken, err)
24 | }
25 |
26 | if response.IsError() {
27 | return responseData, errors.NewAPIErrorWithResponse(callRenewAccessToken, response)
28 | }
29 |
30 | return responseData, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/auth/revoke_access_token.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callRevokeAccessTokenOperation = "CallRevokeAccessToken"
9 |
10 | func CallRevokeAccessToken(httpClient *resty.Client, request RevokeAccessTokenRequest) (RevokeAccessTokenResponse, error) {
11 | var responseData RevokeAccessTokenResponse
12 |
13 | response, err := httpClient.R().
14 | SetResult(&responseData).
15 | SetBody(request).
16 | Post("/v1/auth/token/revoke")
17 |
18 | if err != nil {
19 | return responseData, errors.NewRequestError(callRevokeAccessTokenOperation, err)
20 | }
21 |
22 | if response.IsError() {
23 | return responseData, errors.NewAPIErrorWithResponse(callRevokeAccessTokenOperation, response)
24 | }
25 |
26 | return responseData, nil
27 | }
28 |
--------------------------------------------------------------------------------
/packages/api/auth/universal_auth_login.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callUniversalAuthLoginOperation = "CallUniversalAuthLogin"
9 |
10 | func CallUniversalAuthLogin(httpClient *resty.Client, request UniversalAuthLoginRequest) (credential MachineIdentityAuthLoginResponse, e error) {
11 | var responseData MachineIdentityAuthLoginResponse
12 |
13 | clonedClient := httpClient.Clone()
14 | clonedClient.SetAuthToken("")
15 | clonedClient.SetAuthScheme("")
16 |
17 | response, err := clonedClient.R().
18 | SetResult(&responseData).
19 | SetBody(request).
20 | Post("/v1/auth/universal-auth/login")
21 |
22 | if err != nil {
23 | return responseData, errors.NewRequestError(callUniversalAuthLoginOperation, err)
24 | }
25 |
26 | if response.IsError() {
27 | return responseData, errors.NewAPIErrorWithResponse(callUniversalAuthLoginOperation, response)
28 | }
29 |
30 | return responseData, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/dynamic_secrets/create_lease.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callCreateDynamicSecretLeaseV1Operation = "CallCreateDynamicSecretLeaseV1"
9 |
10 | func CallCreateDynamicSecretLeaseV1(httpClient *resty.Client, request CreateDynamicSecretLeaseV1Request) (CreateDynamicSecretLeaseV1Response, error) {
11 |
12 | createResponse := CreateDynamicSecretLeaseV1Response{}
13 |
14 | req := httpClient.R().
15 | SetResult(&createResponse).
16 | SetBody(request)
17 |
18 | res, err := req.Post("/v1/dynamic-secrets/leases")
19 |
20 | if err != nil {
21 | return CreateDynamicSecretLeaseV1Response{}, errors.NewRequestError(callCreateDynamicSecretLeaseV1Operation, err)
22 | }
23 |
24 | if res.IsError() {
25 | return CreateDynamicSecretLeaseV1Response{}, errors.NewAPIErrorWithResponse(callCreateDynamicSecretLeaseV1Operation, res)
26 | }
27 |
28 | return createResponse, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/dynamic_secrets/delete_lease.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callDeleteDynamicSecretLeaseV1Operation = "CallDeleteDynamicSecretLeaseV1"
9 |
10 | func CallDeleteDynamicSecretLeaseV1(httpClient *resty.Client, request DeleteDynamicSecretLeaseV1Request) (DeleteDynamicSecretLeaseV1Response, error) {
11 |
12 | deleteResponse := DeleteDynamicSecretLeaseV1Response{}
13 |
14 | req := httpClient.R().
15 | SetResult(&deleteResponse).
16 | SetBody(request)
17 |
18 | res, err := req.Delete("/v1/dynamic-secrets/leases/" + request.LeaseId)
19 |
20 | if err != nil {
21 | return DeleteDynamicSecretLeaseV1Response{}, errors.NewRequestError(callDeleteDynamicSecretLeaseV1Operation, err)
22 | }
23 |
24 | if res.IsError() {
25 | return DeleteDynamicSecretLeaseV1Response{}, errors.NewAPIErrorWithResponse(callDeleteDynamicSecretLeaseV1Operation, res)
26 | }
27 |
28 | return deleteResponse, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/dynamic_secrets/get_lease_by_id.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callGetDynamicSecretLeaseByIdV1Operation = "CallGetDynamicSecretLeaseByIdV1"
9 |
10 | func CallGetByDynamicSecretByIdLeaseV1(httpClient *resty.Client, request GetDynamicSecretLeaseByIdV1Request) (GetDynamicSecretLeaseByIdV1Response, error) {
11 |
12 | getByIdResponse := GetDynamicSecretLeaseByIdV1Response{}
13 |
14 | req := httpClient.R().
15 | SetResult(&getByIdResponse).
16 | SetQueryParams(map[string]string{
17 | "projectSlug": request.ProjectSlug,
18 | "environmentSlug": request.EnvironmentSlug,
19 | "path": request.SecretPath,
20 | })
21 |
22 | res, err := req.Get("/v1/dynamic-secrets/leases/" + request.LeaseId)
23 |
24 | if err != nil {
25 | return GetDynamicSecretLeaseByIdV1Response{}, errors.NewRequestError(callGetDynamicSecretLeaseByIdV1Operation, err)
26 | }
27 |
28 | if res.IsError() {
29 | return GetDynamicSecretLeaseByIdV1Response{}, errors.NewAPIErrorWithResponse(callGetDynamicSecretLeaseByIdV1Operation, res)
30 | }
31 |
32 | return getByIdResponse, nil
33 | }
34 |
--------------------------------------------------------------------------------
/packages/api/dynamic_secrets/get_secret_by_name.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callGetDynamicSecretByNameV1Operation = "CallGetDynamicSecretSecretByNameV1"
9 |
10 | func CallGetDynamicSecretByNameV1(httpClient *resty.Client, request GetDynamicSecretByNameV1Request) (GetDynamicSecretByNameV1Response, error) {
11 |
12 | getByNameResponse := GetDynamicSecretByNameV1Response{}
13 |
14 | req := httpClient.R().
15 | SetResult(&getByNameResponse).SetQueryParams(map[string]string{
16 | "projectSlug": request.ProjectSlug,
17 | "environmentSlug": request.EnvironmentSlug,
18 | "path": request.SecretPath,
19 | })
20 |
21 | res, err := req.Get("/v1/dynamic-secrets/" + request.DynamicSecretName)
22 |
23 | if err != nil {
24 | return GetDynamicSecretByNameV1Response{}, errors.NewRequestError(callGetDynamicSecretByNameV1Operation, err)
25 | }
26 |
27 | if res.IsError() {
28 | return GetDynamicSecretByNameV1Response{}, errors.NewAPIErrorWithResponse(callGetDynamicSecretByNameV1Operation, res)
29 | }
30 |
31 | return getByNameResponse, nil
32 | }
33 |
--------------------------------------------------------------------------------
/packages/api/dynamic_secrets/list_lease.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callListDynamicSecretLeaseV1Operation = "CallListDynamicSecretLeaseV1"
9 |
10 | func CallListDynamicSecretLeaseV1(httpClient *resty.Client, request ListDynamicSecretLeaseV1Request) (ListDynamicSecretLeaseV1Response, error) {
11 |
12 | listResponse := ListDynamicSecretLeaseV1Response{}
13 |
14 | req := httpClient.R().
15 | SetResult(&listResponse).
16 | SetQueryParams(map[string]string{
17 | "projectSlug": request.ProjectSlug,
18 | "environmentSlug": request.EnvironmentSlug,
19 | "path": request.SecretPath,
20 | })
21 |
22 | res, err := req.Get("/v1/dynamic-secrets/" + request.DynamicSecretName + "/leases")
23 |
24 | if err != nil {
25 | return ListDynamicSecretLeaseV1Response{}, errors.NewRequestError(callListDynamicSecretLeaseV1Operation, err)
26 | }
27 |
28 | if res.IsError() {
29 | return ListDynamicSecretLeaseV1Response{}, errors.NewAPIErrorWithResponse(callListDynamicSecretLeaseV1Operation, res)
30 | }
31 |
32 | return listResponse, nil
33 | }
34 |
--------------------------------------------------------------------------------
/packages/api/dynamic_secrets/list_secrets.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callListDynamicSecretsV1Operation = "CallListDynamicSecretSecretsV1"
9 |
10 | func CallListDynamicSecretsV1(httpClient *resty.Client, request ListDynamicSecretsV1Request) (ListDynamicSecretsV1Response, error) {
11 |
12 | listDynamicSecretResponse := ListDynamicSecretsV1Response{}
13 |
14 | req := httpClient.R().
15 | SetResult(&listDynamicSecretResponse).
16 | SetQueryParams(map[string]string{
17 | "projectSlug": request.ProjectSlug,
18 | "environmentSlug": request.EnvironmentSlug,
19 | "path": request.SecretPath,
20 | })
21 |
22 | res, err := req.Get("/v1/dynamic-secrets")
23 |
24 | if err != nil {
25 | return ListDynamicSecretsV1Response{}, errors.NewRequestError(callListDynamicSecretsV1Operation, err)
26 | }
27 |
28 | if res.IsError() {
29 | return ListDynamicSecretsV1Response{}, errors.NewAPIErrorWithResponse(callListDynamicSecretsV1Operation, res)
30 | }
31 |
32 | return listDynamicSecretResponse, nil
33 | }
34 |
--------------------------------------------------------------------------------
/packages/api/dynamic_secrets/models.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/infisical/go-sdk/packages/models"
5 | )
6 |
7 | type CreateDynamicSecretLeaseV1Request struct {
8 | DynamicSecretName string `json:"dynamicSecretName"`
9 | ProjectSlug string `json:"projectSlug"`
10 | TTL string `json:"ttl"`
11 | SecretPath string `json:"path"`
12 | EnvironmentSlug string `json:"environmentSlug"`
13 | Config map[string]any `json:"config"`
14 | }
15 |
16 | type CreateDynamicSecretLeaseV1Response struct {
17 | Lease models.DynamicSecretLease `json:"lease"`
18 | DynamicSecret models.DynamicSecret `json:"dynamicSecret"`
19 | Data map[string]any `json:"data"`
20 | }
21 |
22 | type DeleteDynamicSecretLeaseV1Request struct {
23 | LeaseId string `json:"leaseId"`
24 | ProjectSlug string `json:"projectSlug"`
25 | SecretPath string `json:"path"`
26 | EnvironmentSlug string `json:"environmentSlug"`
27 | IsForced bool `json:"isForced"`
28 | }
29 |
30 | type DeleteDynamicSecretLeaseV1Response struct {
31 | Lease models.DynamicSecretLease `json:"lease"`
32 | }
33 |
34 | type RenewDynamicSecretLeaseV1Request struct {
35 | LeaseId string `json:"leaseId"`
36 | TTL string `json:"ttl"`
37 | ProjectSlug string `json:"projectSlug"`
38 | SecretPath string `json:"path"`
39 | EnvironmentSlug string `json:"environmentSlug"`
40 | IsForced bool `json:"isForced"`
41 | }
42 |
43 | type RenewDynamicSecretLeaseV1Response struct {
44 | Lease models.DynamicSecretLease `json:"lease"`
45 | }
46 |
47 | type GetDynamicSecretLeaseByIdV1Request struct {
48 | LeaseId string `json:"leaseId"`
49 | ProjectSlug string `json:"projectSlug"`
50 | SecretPath string `json:"path"`
51 | EnvironmentSlug string `json:"environmentSlug"`
52 | }
53 |
54 | type GetDynamicSecretLeaseByIdV1Response struct {
55 | Lease models.DynamicSecretLeaseWithDynamicSecret `json:"lease"`
56 | }
57 |
58 | type ListDynamicSecretLeaseV1Request struct {
59 | DynamicSecretName string `json:"secretName"`
60 | ProjectSlug string `json:"projectSlug"`
61 | SecretPath string `json:"path"`
62 | EnvironmentSlug string `json:"environmentSlug"`
63 | }
64 |
65 | type ListDynamicSecretLeaseV1Response struct {
66 | Leases []models.DynamicSecretLease `json:"leases"`
67 | }
68 |
69 | type GetDynamicSecretByNameV1Request struct {
70 | DynamicSecretName string `json:"secretName"`
71 | ProjectSlug string `json:"projectSlug"`
72 | SecretPath string `json:"path"`
73 | EnvironmentSlug string `json:"environmentSlug"`
74 | }
75 |
76 | type GetDynamicSecretByNameV1Response struct {
77 | DynamicSecret models.DynamicSecret `json:"dynamicSecret"`
78 | }
79 |
80 | type ListDynamicSecretsV1Request struct {
81 | ProjectSlug string `json:"projectSlug"`
82 | SecretPath string `json:"path"`
83 | EnvironmentSlug string `json:"environmentSlug"`
84 | }
85 |
86 | type ListDynamicSecretsV1Response struct {
87 | DynamicSecrets []models.DynamicSecret `json:"dynamicSecrets"`
88 | }
89 |
--------------------------------------------------------------------------------
/packages/api/dynamic_secrets/renew_lease.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callRenewDynamicSecretLeaseV1Operation = "CallRenewDynamicSecretLeaseV1"
9 |
10 | func CallRenewDynamicSecretLeaseV1(httpClient *resty.Client, request RenewDynamicSecretLeaseV1Request) (RenewDynamicSecretLeaseV1Response, error) {
11 |
12 | renewResponse := RenewDynamicSecretLeaseV1Response{}
13 |
14 | req := httpClient.R().
15 | SetResult(&renewResponse).
16 | SetBody(request)
17 |
18 | res, err := req.Post("/v1/dynamic-secrets/leases/" + request.LeaseId + "/renew")
19 |
20 | if err != nil {
21 | return RenewDynamicSecretLeaseV1Response{}, errors.NewRequestError(callRenewDynamicSecretLeaseV1Operation, err)
22 | }
23 |
24 | if res.IsError() {
25 | return RenewDynamicSecretLeaseV1Response{}, errors.NewAPIErrorWithResponse(callRenewDynamicSecretLeaseV1Operation, res)
26 | }
27 |
28 | return renewResponse, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/folders/create_folder.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callCreateFolderV1Operation = "CallCreateFolderV1"
9 |
10 | func CallCreateFolderV1(httpClient *resty.Client, request CreateFolderV1Request) (CreateFolderV1Response, error) {
11 |
12 | createResponse := CreateFolderV1Response{}
13 |
14 | req := httpClient.R().
15 | SetResult(&createResponse).
16 | SetBody(request)
17 |
18 | res, err := req.Post("/v1/folders")
19 |
20 | if err != nil {
21 | return CreateFolderV1Response{}, errors.NewRequestError(callCreateFolderV1Operation, err)
22 | }
23 |
24 | if res.IsError() {
25 | return CreateFolderV1Response{}, errors.NewAPIErrorWithResponse(callCreateFolderV1Operation, res)
26 | }
27 |
28 | return createResponse, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/folders/delete_folder.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callDeleteFolderV1Operation = "CallDeleteFolderV1"
11 |
12 | func CallDeleteFolderV1(httpClient *resty.Client, request DeleteFolderV1Request) (DeleteFolderV1Response, error) {
13 |
14 | deleteResponse := DeleteFolderV1Response{}
15 |
16 | // Either folderID or folderName must be provided
17 | var folderIdOrName string
18 | if request.FolderID != "" {
19 | folderIdOrName = request.FolderID
20 | } else if request.FolderName != "" {
21 | folderIdOrName = request.FolderName
22 | } else {
23 | return DeleteFolderV1Response{}, fmt.Errorf("CallDeleteFolderV1: Either folderID or folderName must be provided")
24 | }
25 |
26 | req := httpClient.R().
27 | SetResult(&deleteResponse).
28 | SetBody(request)
29 |
30 | res, err := req.Delete(fmt.Sprintf("/v1/folders/%s", folderIdOrName))
31 |
32 | if err != nil {
33 | return DeleteFolderV1Response{}, errors.NewRequestError(callDeleteFolderV1Operation, err)
34 | }
35 |
36 | if res.IsError() {
37 | return DeleteFolderV1Response{}, errors.NewAPIErrorWithResponse(callDeleteFolderV1Operation, res)
38 | }
39 |
40 | return deleteResponse, nil
41 | }
42 |
--------------------------------------------------------------------------------
/packages/api/folders/list_folders.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callListFoldersV1Operation = "CallListFoldersV1"
9 |
10 | func CallListFoldersV1(httpClient *resty.Client, request ListFoldersV1Request) (ListFoldersV1Response, error) {
11 |
12 | secretsResponse := ListFoldersV1Response{}
13 |
14 | queryParams := map[string]string{
15 | "workspaceId": request.ProjectID,
16 | "environment": request.Environment,
17 | }
18 |
19 | if request.Path != "" {
20 | queryParams["path"] = request.Path
21 | }
22 |
23 | res, err := httpClient.R().
24 | SetResult(&secretsResponse).
25 | SetQueryParams(queryParams).Get("/v1/folders")
26 |
27 | if err != nil {
28 | return ListFoldersV1Response{}, errors.NewRequestError(callListFoldersV1Operation, err)
29 | }
30 |
31 | if res.IsError() {
32 | return ListFoldersV1Response{}, errors.NewAPIErrorWithResponse(callListFoldersV1Operation, res)
33 | }
34 |
35 | return secretsResponse, nil
36 | }
37 |
--------------------------------------------------------------------------------
/packages/api/folders/models.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/infisical/go-sdk/packages/models"
5 | )
6 |
7 | // List folders
8 | type ListFoldersV1Request struct {
9 | ProjectID string `json:"workspaceId"`
10 | Environment string `json:"environment"`
11 | Path string `json:"path,omitempty"`
12 | }
13 |
14 | type ListFoldersV1Response struct {
15 | Folders []models.Folder `json:"folders"`
16 | }
17 |
18 | // Update folder
19 | type UpdateFolderV1Request struct {
20 | FolderID string `json:"-"`
21 |
22 | ProjectID string `json:"workspaceId"`
23 | Environment string `json:"environment"`
24 | NewName string `json:"name"`
25 | Path string `json:"path,omitempty"`
26 | }
27 |
28 | type UpdateFolderV1Response struct {
29 | Folder models.Folder `json:"folder"`
30 | }
31 |
32 | // Create folder
33 | type CreateFolderV1Request struct {
34 | ProjectID string `json:"workspaceId"`
35 | Environment string `json:"environment"`
36 | Name string `json:"name"`
37 | Path string `json:"path,omitempty"`
38 | }
39 |
40 | type CreateFolderV1Response struct {
41 | Folder models.Folder `json:"folder"`
42 | }
43 |
44 | // Delete folder
45 | type DeleteFolderV1Request struct {
46 | // Either FolderID or folderName must be provided
47 | FolderID string `json:"-"`
48 | FolderName string `json:"-"`
49 |
50 | ProjectID string `json:"workspaceId"`
51 | Environment string `json:"environment"`
52 | Path string `json:"path,omitempty"`
53 | }
54 |
55 | type DeleteFolderV1Response struct {
56 | Folder models.Folder `json:"folder"`
57 | }
58 |
--------------------------------------------------------------------------------
/packages/api/folders/update_folder.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callUpdateFolderV1Operation = "CallUpdateFolderV1"
11 |
12 | func CallUpdateFolderV1(httpClient *resty.Client, request UpdateFolderV1Request) (UpdateFolderV1Response, error) {
13 |
14 | updateResponse := UpdateFolderV1Response{}
15 |
16 | req := httpClient.R().
17 | SetResult(&updateResponse).
18 | SetBody(request)
19 |
20 | res, err := req.Patch(fmt.Sprintf("/v1/folders/%s", request.FolderID))
21 |
22 | if err != nil {
23 | return UpdateFolderV1Response{}, errors.NewRequestError(callUpdateFolderV1Operation, err)
24 | }
25 |
26 | if res.IsError() {
27 | return UpdateFolderV1Response{}, errors.NewAPIErrorWithResponse(callUpdateFolderV1Operation, res)
28 | }
29 |
30 | return updateResponse, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/kms/create_key.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callKmsCreateKeyOperationV1 = "CallKmsCreateKeyV1"
9 |
10 | func CallKmsCreateKeyV1(httpClient *resty.Client, request KmsCreateKeyV1Request) (KmsCreateKeyV1Response, error) {
11 | kmsCreateKeyResponse := KmsCreateKeyV1Response{}
12 |
13 | res, err := httpClient.R().
14 | SetResult(&kmsCreateKeyResponse).
15 | SetBody(request).
16 | Post("/v1/kms/keys")
17 |
18 | if err != nil {
19 | return KmsCreateKeyV1Response{}, errors.NewRequestError(callKmsCreateKeyOperationV1, err)
20 | }
21 |
22 | if res.IsError() {
23 | return KmsCreateKeyV1Response{}, errors.NewAPIErrorWithResponse(callKmsCreateKeyOperationV1, res)
24 | }
25 |
26 | return kmsCreateKeyResponse, nil
27 | }
28 |
--------------------------------------------------------------------------------
/packages/api/kms/decrypt_data.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callKmsDecryptDataOperationV1 = "CallKmsDecryptDataV1"
11 |
12 | func CallKmsDecryptDataV1(httpClient *resty.Client, request KmsDecryptDataV1Request) (KmsDecryptDataV1Response, error) {
13 | kmsDecryptDataResponse := KmsDecryptDataV1Response{}
14 |
15 | res, err := httpClient.R().
16 | SetResult(&kmsDecryptDataResponse).
17 | SetBody(request).
18 | Post(fmt.Sprintf("/v1/kms/keys/%s/decrypt", request.KeyId))
19 |
20 | if err != nil {
21 | return KmsDecryptDataV1Response{}, errors.NewRequestError(callKmsDecryptDataOperationV1, err)
22 | }
23 |
24 | if res.IsError() {
25 | return KmsDecryptDataV1Response{}, errors.NewAPIErrorWithResponse(callKmsDecryptDataOperationV1, res)
26 | }
27 |
28 | return kmsDecryptDataResponse, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/kms/delete_key.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callKmsDeleteKeyOperationV1 = "CallKmsDeleteKeyV1"
11 |
12 | func CallKmsDeleteKeyV1(httpClient *resty.Client, request KmsDeleteKeyV1Request) (KmsDeleteKeyV1Response, error) {
13 | kmsDeleteKeyResponse := KmsDeleteKeyV1Response{}
14 |
15 | res, err := httpClient.R().
16 | SetResult(&kmsDeleteKeyResponse).
17 | SetBody(request).
18 | Delete(fmt.Sprintf("/v1/kms/keys/%s", request.KeyId))
19 |
20 | if err != nil {
21 | return KmsDeleteKeyV1Response{}, errors.NewRequestError(callKmsDeleteKeyOperationV1, err)
22 | }
23 |
24 | if res.IsError() {
25 | return KmsDeleteKeyV1Response{}, errors.NewAPIErrorWithResponse(callKmsDeleteKeyOperationV1, res)
26 | }
27 |
28 | return kmsDeleteKeyResponse, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/kms/encrypt_data.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callKmsEncryptDataOperationV1 = "CallKmsEncryptDataV1"
11 |
12 | func CallKmsEncryptDataV1(httpClient *resty.Client, request KmsEncryptDataV1Request) (KmsEncryptDataV1Response, error) {
13 | kmsEncryptDataResponse := KmsEncryptDataV1Response{}
14 |
15 | res, err := httpClient.R().
16 | SetResult(&kmsEncryptDataResponse).
17 | SetBody(request).
18 | Post(fmt.Sprintf("/v1/kms/keys/%s/encrypt", request.KeyId))
19 |
20 | if err != nil {
21 | return KmsEncryptDataV1Response{}, errors.NewRequestError(callKmsEncryptDataOperationV1, err)
22 | }
23 |
24 | if res.IsError() {
25 | return KmsEncryptDataV1Response{}, errors.NewAPIErrorWithResponse(callKmsEncryptDataOperationV1, res)
26 | }
27 |
28 | return kmsEncryptDataResponse, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/kms/get_key_by_name.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callKmsGetKeyByNameOperationV1 = "CallKmsGetKeyByNameV1"
11 |
12 | func CallKmsGetKeyByNameV1(httpClient *resty.Client, request KmsGetKeyByNameV1Request) (KmsGetKeyV1Response, error) {
13 | kmsGetKeyByNameResponse := KmsGetKeyV1Response{}
14 |
15 | res, err := httpClient.R().
16 | SetResult(&kmsGetKeyByNameResponse).
17 | Get(fmt.Sprintf("/v1/kms/keys/key-name/%s?projectId=%s", request.KeyName, request.ProjectId))
18 |
19 | if err != nil {
20 | return KmsGetKeyV1Response{}, errors.NewRequestError(callKmsGetKeyByNameOperationV1, err)
21 | }
22 |
23 | if res.IsError() {
24 | return KmsGetKeyV1Response{}, errors.NewAPIErrorWithResponse(callKmsGetKeyByNameOperationV1, res)
25 | }
26 |
27 | return kmsGetKeyByNameResponse, nil
28 | }
29 |
--------------------------------------------------------------------------------
/packages/api/kms/get_public_key.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callKmsGetPublicKeyOperationV1 = "CallKmsGetPublicKeyV1"
11 |
12 | func CallKmsGetPublicKeyV1(httpClient *resty.Client, request KmsGetPublicKeyV1Request) (KmsGetPublicKeyV1Response, error) {
13 | kmsGetPublicKeyResponse := KmsGetPublicKeyV1Response{}
14 |
15 | res, err := httpClient.R().
16 | SetResult(&kmsGetPublicKeyResponse).
17 | Get(fmt.Sprintf("/v1/kms/keys/%s/public-key", request.KeyId))
18 |
19 | if err != nil {
20 | return KmsGetPublicKeyV1Response{}, errors.NewRequestError(callKmsGetPublicKeyOperationV1, err)
21 | }
22 |
23 | if res.IsError() {
24 | return KmsGetPublicKeyV1Response{}, errors.NewAPIErrorWithResponse(callKmsGetPublicKeyOperationV1, res)
25 | }
26 |
27 | return kmsGetPublicKeyResponse, nil
28 | }
29 |
--------------------------------------------------------------------------------
/packages/api/kms/get_signing_algorithms.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 |
8 | "github.com/infisical/go-sdk/packages/errors"
9 | )
10 |
11 | const callKmsGetSigningAlgorithmsOperationV1 = "CallKmsGetSigningAlgorithmsV1"
12 |
13 | func CallKmsGetSigningAlgorithmsV1(httpClient *resty.Client, request KmsListSigningAlgorithmsV1Request) (KmsListSigningAlgorithmsV1Response, error) {
14 | kmsListSigningAlgorithmsResponse := KmsListSigningAlgorithmsV1Response{}
15 |
16 | res, err := httpClient.R().
17 | SetResult(&kmsListSigningAlgorithmsResponse).
18 | Get(fmt.Sprintf("/v1/kms/keys/%s/signing-algorithms", request.KeyId))
19 |
20 | if err != nil {
21 | return KmsListSigningAlgorithmsV1Response{}, errors.NewRequestError(callKmsGetSigningAlgorithmsOperationV1, err)
22 | }
23 |
24 | if res.IsError() {
25 | return KmsListSigningAlgorithmsV1Response{}, errors.NewAPIErrorWithResponse(callKmsGetSigningAlgorithmsOperationV1, res)
26 | }
27 |
28 | return kmsListSigningAlgorithmsResponse, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/kms/models.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | type KmsEncryptDataV1Request struct {
4 | KeyId string
5 | Plaintext string `json:"plaintext"`
6 | }
7 |
8 | type KmsEncryptDataV1Response struct {
9 | Ciphertext string `json:"ciphertext"`
10 | }
11 |
12 | type KmsDecryptDataV1Request struct {
13 | KeyId string
14 | Ciphertext string `json:"ciphertext"`
15 | }
16 |
17 | type KmsDecryptDataV1Response struct {
18 | Plaintext string `json:"plaintext"`
19 | }
20 |
21 | type KmsSignDataV1Request struct {
22 | KeyId string
23 | Data string `json:"data"`
24 | SigningAlgorithm string `json:"signingAlgorithm"`
25 | IsDigest bool `json:"isDigest"`
26 | }
27 |
28 | type KmsSignDataV1Response struct {
29 | Signature string `json:"signature"`
30 | KeyId string `json:"keyId"`
31 | SigningAlgorithm string `json:"signingAlgorithm"`
32 | }
33 |
34 | type KmsVerifyDataV1Request struct {
35 | KeyId string
36 | Data string `json:"data"` // Data must be base64 encoded
37 | Signature string `json:"signature"`
38 | SigningAlgorithm string `json:"signingAlgorithm"`
39 | IsDigest bool `json:"isDigest"`
40 | }
41 |
42 | type KmsVerifyDataV1Response struct {
43 | SignatureValid bool `json:"signatureValid"`
44 | KeyId string `json:"keyId"`
45 | SigningAlgorithm string `json:"signingAlgorithm"`
46 | }
47 |
48 | type KmsListSigningAlgorithmsV1Request struct {
49 | KeyId string
50 | }
51 |
52 | type KmsListSigningAlgorithmsV1Response struct {
53 | SigningAlgorithms []string `json:"signingAlgorithms"`
54 | }
55 |
56 | type KmsGetPublicKeyV1Request struct {
57 | KeyId string
58 | }
59 |
60 | type KmsGetPublicKeyV1Response struct {
61 | PublicKey string `json:"publicKey"`
62 | }
63 |
64 | type KmsCreateKeyV1Request struct {
65 | // KeyUsage is the usage of the key. Can be either sign-verify or encrypt-decrypt
66 | KeyUsage string `json:"keyUsage"`
67 |
68 | // Description is the description of the key.
69 | Description string `json:"description"`
70 |
71 | // Name is the name of the key.
72 | Name string `json:"name"`
73 |
74 | // EncryptionAlgorithm is the algorithm that will be used for the key itself.
75 | // `sign-verify algorithms`: `rsa-4096`, `ecc-nist-p256`
76 | // `encrypt-decrypt algorithms`: `aes-256-gcm`, `aes-128-gcm`
77 | EncryptionAlgorithm string `json:"encryptionAlgorithm"`
78 |
79 | // ProjectId is the project ID that the key will be created in.
80 | ProjectId string `json:"projectId"`
81 | }
82 |
83 | type KmsCreateKeyV1Response struct {
84 | Key KmsKey `json:"key"`
85 | }
86 |
87 | type KmsDeleteKeyV1Request struct {
88 | KeyId string
89 | }
90 |
91 | type KmsDeleteKeyV1Response struct {
92 | Key KmsKey `json:"key"`
93 | }
94 |
95 | type KmsGetKeyByNameV1Request struct {
96 | KeyName string
97 | ProjectId string
98 | }
99 |
100 | type KmsGetKeyV1Response struct {
101 | Key KmsKey `json:"key"`
102 | }
103 |
104 | type KmsKey struct {
105 | KeyId string `json:"id"`
106 | Description string `json:"description"`
107 | IsDisabled bool `json:"isDisabled"`
108 | OrgId string `json:"orgId"`
109 | Name string `json:"name"`
110 | ProjectId string `json:"projectId"`
111 | KeyUsage string `json:"keyUsage"`
112 | Version int `json:"version"`
113 | EncryptionAlgorithm string `json:"encryptionAlgorithm"`
114 | }
115 |
--------------------------------------------------------------------------------
/packages/api/kms/sign_data.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callKmsSignDataOperationV1 = "CallKmsSignDataV1"
11 |
12 | func CallKmsSignDataV1(httpClient *resty.Client, request KmsSignDataV1Request) (KmsSignDataV1Response, error) {
13 | kmsSignDataResponse := KmsSignDataV1Response{}
14 |
15 | res, err := httpClient.R().
16 | SetResult(&kmsSignDataResponse).
17 | SetBody(request).
18 | Post(fmt.Sprintf("/v1/kms/keys/%s/sign", request.KeyId))
19 |
20 | if err != nil {
21 | return KmsSignDataV1Response{}, errors.NewRequestError(callKmsSignDataOperationV1, err)
22 | }
23 |
24 | if res.IsError() {
25 | return KmsSignDataV1Response{}, errors.NewAPIErrorWithResponse(callKmsSignDataOperationV1, res)
26 | }
27 |
28 | return kmsSignDataResponse, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/kms/verify_data.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callKmsVerifyDataOperationV1 = "CallKmsVerifyDataV1"
11 |
12 | func CallKmsVerifyDataV1(httpClient *resty.Client, request KmsVerifyDataV1Request) (KmsVerifyDataV1Response, error) {
13 | kmsVerifyDataResponse := KmsVerifyDataV1Response{}
14 |
15 | res, err := httpClient.R().
16 | SetResult(&kmsVerifyDataResponse).
17 | SetBody(request).
18 | Post(fmt.Sprintf("/v1/kms/keys/%s/verify", request.KeyId))
19 |
20 | if err != nil {
21 | return KmsVerifyDataV1Response{}, errors.NewRequestError(callKmsVerifyDataOperationV1, err)
22 | }
23 |
24 | if res.IsError() {
25 | return KmsVerifyDataV1Response{}, errors.NewAPIErrorWithResponse(callKmsVerifyDataOperationV1, res)
26 | }
27 |
28 | return kmsVerifyDataResponse, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/secrets/bulk_create_secrets.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callBatchCreateSecretV3RawOperation = "CallBatchCreateSecretV3Raw"
9 |
10 | func CallBatchCreateSecretV3(httpClient *resty.Client, request BatchCreateSecretsV3RawRequest) (BatchCreateSecretsV3RawResponse, error) {
11 |
12 | createBatchResponse := BatchCreateSecretsV3RawResponse{}
13 |
14 | req := httpClient.R().
15 | SetResult(&createBatchResponse).
16 | SetBody(request)
17 |
18 | res, err := req.Post("/v3/secrets/batch/raw")
19 |
20 | if err != nil {
21 | return BatchCreateSecretsV3RawResponse{}, errors.NewRequestError(callBatchCreateSecretV3RawOperation, err)
22 | }
23 |
24 | if res.IsError() {
25 | return BatchCreateSecretsV3RawResponse{}, errors.NewAPIErrorWithResponse(callBatchCreateSecretV3RawOperation, res)
26 | }
27 |
28 | for idx := range createBatchResponse.Secrets {
29 |
30 | secretPath := request.SecretPath
31 |
32 | if secretPath == "" {
33 | secretPath = "/"
34 | }
35 |
36 | createBatchResponse.Secrets[idx].SecretPath = secretPath
37 | }
38 |
39 | return createBatchResponse, nil
40 | }
41 |
--------------------------------------------------------------------------------
/packages/api/secrets/create_secret.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callCreateSecretV3RawOperation = "CallCreateSecretV3Raw"
11 |
12 | func CallCreateSecretV3(httpClient *resty.Client, request CreateSecretV3RawRequest) (CreateSecretV3RawResponse, error) {
13 |
14 | createResponse := CreateSecretV3RawResponse{}
15 |
16 | req := httpClient.R().
17 | SetResult(&createResponse).
18 | SetBody(request)
19 |
20 | res, err := req.Post(fmt.Sprintf("/v3/secrets/raw/%s", request.SecretKey))
21 |
22 | if err != nil {
23 | return CreateSecretV3RawResponse{}, errors.NewRequestError(callCreateSecretV3RawOperation, err)
24 | }
25 |
26 | if res.IsError() {
27 | return CreateSecretV3RawResponse{}, errors.NewAPIErrorWithResponse(callCreateSecretV3RawOperation, res)
28 | }
29 |
30 | return createResponse, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/secrets/delete_secret.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callDeleteSecretV3RawOperation = "CallDeleteSecretV3Raw"
11 |
12 | func CallDeleteSecretV3(httpClient *resty.Client, request DeleteSecretV3RawRequest) (DeleteSecretV3RawResponse, error) {
13 |
14 | deleteResponse := DeleteSecretV3RawResponse{}
15 |
16 | req := httpClient.R().
17 | SetResult(&deleteResponse).
18 | SetBody(request)
19 |
20 | res, err := req.Delete(fmt.Sprintf("/v3/secrets/raw/%s", request.SecretKey))
21 |
22 | if err != nil {
23 | return DeleteSecretV3RawResponse{}, errors.NewRequestError(callDeleteSecretV3RawOperation, err)
24 | }
25 |
26 | if res.IsError() {
27 | return DeleteSecretV3RawResponse{}, errors.NewAPIErrorWithResponse(callDeleteSecretV3RawOperation, res)
28 | }
29 |
30 | return deleteResponse, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/secrets/list_secrets.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 |
7 | "github.com/go-resty/resty/v2"
8 | "github.com/hashicorp/golang-lru/v2/expirable"
9 | "github.com/infisical/go-sdk/packages/errors"
10 | "github.com/infisical/go-sdk/packages/util"
11 | )
12 |
13 | const callListSecretsV3RawOperation = "CallListSecretsV3Raw"
14 |
15 | func CallListSecretsV3(cache *expirable.LRU[string, interface{}], httpClient *resty.Client, request ListSecretsV3RawRequest) (ListSecretsV3RawResponse, error) {
16 | var cacheKey string
17 |
18 | if cache != nil {
19 | reqBytes, err := json.Marshal(request)
20 | if err != nil {
21 | return ListSecretsV3RawResponse{}, err
22 | }
23 | cacheKey = util.ComputeCacheKeyFromBytes(reqBytes, callListSecretsV3RawOperation)
24 | if cached, found := cache.Get(cacheKey); found {
25 | if response, ok := cached.(ListSecretsV3RawResponse); ok {
26 | return response, nil
27 | }
28 | cache.Remove(cacheKey)
29 | }
30 | }
31 |
32 | secretsResponse := ListSecretsV3RawResponse{}
33 |
34 | if request.SecretPath == "" {
35 | request.SecretPath = "/"
36 | }
37 |
38 | res, err := httpClient.R().
39 | SetResult(&secretsResponse).
40 | SetQueryParams(map[string]string{
41 | "workspaceId": request.ProjectID,
42 | "workspaceSlug": request.ProjectSlug,
43 | "environment": request.Environment,
44 | "secretPath": request.SecretPath,
45 | "expandSecretReferences": fmt.Sprintf("%t", request.ExpandSecretReferences),
46 | "include_imports": fmt.Sprintf("%t", request.IncludeImports),
47 | "recursive": fmt.Sprintf("%t", request.Recursive),
48 | }).Get("/v3/secrets/raw")
49 |
50 | if err != nil {
51 | return ListSecretsV3RawResponse{}, errors.NewRequestError(callListSecretsV3RawOperation, err)
52 | }
53 |
54 | if res.IsError() {
55 | return ListSecretsV3RawResponse{}, errors.NewAPIErrorWithResponse(callListSecretsV3RawOperation, res)
56 | }
57 |
58 | if cache != nil {
59 | cache.Add(cacheKey, secretsResponse)
60 | }
61 |
62 | return secretsResponse, nil
63 | }
64 |
--------------------------------------------------------------------------------
/packages/api/secrets/models.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import "github.com/infisical/go-sdk/packages/models"
4 |
5 | // List secrets
6 | type ListSecretsV3RawRequest struct {
7 | AttachToProcessEnv bool `json:"-"`
8 |
9 | // ProjectId and ProjectSlug are used to fetch secrets from the project. Only one of them is required.
10 | ProjectID string `json:"workspaceId,omitempty"`
11 | ProjectSlug string `json:"workspaceSlug,omitempty"`
12 | Environment string `json:"environment"`
13 | ExpandSecretReferences bool `json:"expandSecretReferences"`
14 | IncludeImports bool `json:"include_imports"`
15 | Recursive bool `json:"recursive"`
16 | SecretPath string `json:"secretPath,omitempty"`
17 | }
18 |
19 | type ListSecretsV3RawResponse struct {
20 | Secrets []models.Secret `json:"secrets"`
21 | Imports []models.SecretImport `json:"imports"`
22 | }
23 |
24 | // Retrieve secret
25 |
26 | type RetrieveSecretV3RawRequest struct {
27 | SecretKey string `json:"secretKey"`
28 |
29 | ProjectSlug string `json:"workspaceSlug,omitempty"`
30 | ProjectID string `json:"workspaceId,omitempty"`
31 | Environment string `json:"environment"`
32 | SecretPath string `json:"secretPath,omitempty"`
33 | Type string `json:"type,omitempty"`
34 | IncludeImports bool `json:"include_imports"`
35 | ExpandSecretReferences bool `json:"expandSecretReferences"`
36 |
37 | Version int `json:"version,omitempty"`
38 | }
39 |
40 | type RetrieveSecretV3RawResponse struct {
41 | Secret models.Secret `json:"secret"`
42 | }
43 |
44 | // Update secret
45 | type UpdateSecretV3RawRequest struct {
46 | SecretKey string `json:"-"`
47 |
48 | ProjectID string `json:"workspaceId"`
49 | Environment string `json:"environment"`
50 | SecretPath string `json:"secretPath,omitempty"`
51 | Type string `json:"type,omitempty"`
52 |
53 | NewSecretValue string `json:"secretValue,omitempty"`
54 | NewSkipMultilineEncoding bool `json:"skipMultilineEncoding,omitempty"`
55 | }
56 |
57 | type UpdateSecretV3RawResponse struct {
58 | Secret models.Secret `json:"secret"`
59 | }
60 |
61 | // Create secret
62 | type CreateSecretV3RawRequest struct {
63 | SecretKey string `json:"-"`
64 |
65 | ProjectID string `json:"workspaceId"`
66 | Environment string `json:"environment"`
67 | SecretPath string `json:"secretPath,omitempty"`
68 | Type string `json:"type,omitempty"`
69 | SecretComment string `json:"secretComment,omitempty"`
70 | SkipMultiLineEncoding bool `json:"skipMultilineEncoding"`
71 | SecretValue string `json:"secretValue"`
72 | }
73 |
74 | type CreateSecretV3RawResponse struct {
75 | Secret models.Secret `json:"secret"`
76 | }
77 |
78 | // Delete secret
79 | type DeleteSecretV3RawRequest struct {
80 | SecretKey string `json:"-"`
81 |
82 | ProjectID string `json:"workspaceId"`
83 | Environment string `json:"environment"`
84 | SecretPath string `json:"secretPath,omitempty"`
85 | Type string `json:"type,omitempty"`
86 | }
87 |
88 | type DeleteSecretV3RawResponse struct {
89 | Secret models.Secret `json:"secret"`
90 | }
91 |
92 | type BatchCreateSecret struct {
93 | SecretKey string `json:"secretKey"`
94 | SecretValue string `json:"secretValue"`
95 | SecretComment string `json:"secretComment,omitempty"`
96 | SkipMultiLineEncoding bool `json:"skipMultilineEncoding,omitempty"`
97 | SecretMetadata []models.SecretMetadata `json:"secretMetadata,omitempty"`
98 | TagIDs []string `json:"tagIds,omitempty"`
99 | }
100 |
101 | type BatchCreateSecretsV3RawRequest struct {
102 | Environment string `json:"environment"`
103 | ProjectID string `json:"workspaceId"`
104 | SecretPath string `json:"secretPath,omitempty"`
105 | Secrets []BatchCreateSecret `json:"secrets"`
106 | }
107 |
108 | type BatchCreateSecretsV3RawResponse struct {
109 | Secrets []models.Secret `json:"secrets"`
110 | }
111 |
--------------------------------------------------------------------------------
/packages/api/secrets/retrieve_secret.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 | "fmt"
7 |
8 | "github.com/go-resty/resty/v2"
9 | "github.com/hashicorp/golang-lru/v2/expirable"
10 | sdkErrors "github.com/infisical/go-sdk/packages/errors"
11 | "github.com/infisical/go-sdk/packages/util"
12 | )
13 |
14 | const callRetrieveSecretV3RawOperation = "CallRetrieveSecretV3Raw"
15 |
16 | func CallRetrieveSecretV3(cache *expirable.LRU[string, interface{}], httpClient *resty.Client, request RetrieveSecretV3RawRequest) (RetrieveSecretV3RawResponse, error) {
17 | var cacheKey string
18 |
19 | if cache != nil {
20 | reqBytes, err := json.Marshal(request)
21 | if err != nil {
22 | return RetrieveSecretV3RawResponse{}, err
23 | }
24 | cacheKey = util.ComputeCacheKeyFromBytes(reqBytes, callRetrieveSecretV3RawOperation)
25 | if cached, found := cache.Get(cacheKey); found {
26 | if response, ok := cached.(RetrieveSecretV3RawResponse); ok {
27 | return response, nil
28 | }
29 | cache.Remove(cacheKey)
30 | }
31 | }
32 |
33 | retrieveResponse := RetrieveSecretV3RawResponse{}
34 |
35 | if request.Type == "" {
36 | request.Type = "shared"
37 | }
38 |
39 | if request.SecretPath == "" {
40 | request.SecretPath = "/"
41 | }
42 |
43 | queryParams := map[string]string{
44 | "environment": request.Environment,
45 | "secretPath": request.SecretPath,
46 | "expandSecretReferences": fmt.Sprintf("%t", request.ExpandSecretReferences),
47 | "include_imports": fmt.Sprintf("%t", request.IncludeImports),
48 | "type": request.Type,
49 | }
50 | if request.ProjectID != "" {
51 | queryParams["workspaceId"] = request.ProjectID
52 | } else if request.ProjectSlug != "" {
53 | queryParams["workspaceSlug"] = request.ProjectSlug
54 | } else {
55 | return RetrieveSecretV3RawResponse{}, errors.New("projectId or projectSlug is required")
56 | }
57 |
58 | if request.Version != 0 {
59 | queryParams["version"] = fmt.Sprintf("%d", request.Version)
60 | }
61 |
62 | req := httpClient.R().
63 | SetResult(&retrieveResponse).
64 | SetQueryParams(queryParams)
65 |
66 | res, err := req.Get(fmt.Sprintf("/v3/secrets/raw/%s", request.SecretKey))
67 |
68 | if err != nil {
69 | return RetrieveSecretV3RawResponse{}, sdkErrors.NewRequestError(callRetrieveSecretV3RawOperation, err)
70 | }
71 |
72 | if res.IsError() {
73 | return RetrieveSecretV3RawResponse{}, sdkErrors.NewAPIErrorWithResponse(callRetrieveSecretV3RawOperation, res)
74 | }
75 |
76 | if cache != nil {
77 | cache.Add(cacheKey, retrieveResponse)
78 | }
79 |
80 | return retrieveResponse, nil
81 | }
82 |
--------------------------------------------------------------------------------
/packages/api/secrets/update_secret.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callUpdateSecretV3RawOperation = "CallUpdateSecretV3Raw"
11 |
12 | func CallUpdateSecretV3(httpClient *resty.Client, request UpdateSecretV3RawRequest) (UpdateSecretV3RawResponse, error) {
13 |
14 | updateResponse := UpdateSecretV3RawResponse{}
15 |
16 | req := httpClient.R().
17 | SetResult(&updateResponse).
18 | SetBody(request)
19 |
20 | res, err := req.Patch(fmt.Sprintf("/v3/secrets/raw/%s", request.SecretKey))
21 |
22 | if err != nil {
23 | return UpdateSecretV3RawResponse{}, errors.NewRequestError(callUpdateSecretV3RawOperation, err)
24 | }
25 |
26 | if res.IsError() {
27 | return UpdateSecretV3RawResponse{}, errors.NewAPIErrorWithResponse(callUpdateSecretV3RawOperation, res)
28 | }
29 |
30 | return updateResponse, nil
31 | }
32 |
--------------------------------------------------------------------------------
/packages/api/ssh/add_ssh_host.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callAddSshHostOperation = "CallAddSshHostV1"
9 |
10 | func CallAddSshHostV1(httpClient *resty.Client, body AddSshHostV1Request) (AddSshHostV1Response, error) {
11 | resp := AddSshHostV1Response{}
12 |
13 | res, err := httpClient.R().
14 | SetBody(body).
15 | SetResult(&resp).
16 | Post("/v1/ssh/hosts")
17 |
18 | if err != nil {
19 | return AddSshHostV1Response{}, errors.NewRequestError(callAddSshHostOperation, err)
20 | }
21 |
22 | if res.IsError() {
23 | return AddSshHostV1Response{}, errors.NewAPIErrorWithResponse(callAddSshHostOperation, res)
24 | }
25 |
26 | return resp, nil
27 | }
28 |
--------------------------------------------------------------------------------
/packages/api/ssh/get_ssh_host_host_ca_pk.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | func GetSshHostHostCaPublicKeyV1(httpClient *resty.Client, sshHostId string) (string, error) {
9 | res, err := httpClient.R().
10 | Get("/v1/ssh/hosts/" + sshHostId + "/host-ca-public-key")
11 |
12 | if err != nil {
13 | return "", errors.NewRequestError("GetSshHostHostCaPublicKeyV1", err)
14 | }
15 |
16 | if res.IsError() {
17 | return "", errors.NewAPIErrorWithResponse("GetSshHostHostCaPublicKeyV1", res)
18 | }
19 |
20 | return res.String(), nil
21 | }
22 |
--------------------------------------------------------------------------------
/packages/api/ssh/get_ssh_host_user_ca_pk.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | func GetSshHostUserCaPublicKeyV1(httpClient *resty.Client, sshHostId string) (string, error) {
9 | res, err := httpClient.R().
10 | Get("/v1/ssh/hosts/" + sshHostId + "/user-ca-public-key")
11 |
12 | if err != nil {
13 | return "", errors.NewRequestError("GetSshHostUserCaPublicKeyV1", err)
14 | }
15 |
16 | if res.IsError() {
17 | return "", errors.NewAPIErrorWithResponse("GetSshHostUserCaPublicKeyV1", res)
18 | }
19 |
20 | return res.String(), nil
21 | }
22 |
--------------------------------------------------------------------------------
/packages/api/ssh/get_ssh_hosts.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callGetSshHostsOperation = "CallGetSshHostsV1"
9 |
10 | func GetSshHostsV1(httpClient *resty.Client, _ GetSshHostsV1Request) (GetSshHostsV1Response, error) {
11 | var getSshHostsResponse GetSshHostsV1Response
12 |
13 | res, err := httpClient.R().
14 | SetResult(&getSshHostsResponse).
15 | Get("/v1/ssh/hosts")
16 |
17 | if err != nil {
18 | return nil, errors.NewRequestError(callGetSshHostsOperation, err)
19 | }
20 |
21 | if res.IsError() {
22 | return nil, errors.NewAPIErrorWithResponse(callGetSshHostsOperation, res)
23 | }
24 |
25 | return getSshHostsResponse, nil
26 | }
27 |
--------------------------------------------------------------------------------
/packages/api/ssh/issue_ssh_creds.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callIssueSshCredsOperation = "CallIssueSshCredsV1"
9 |
10 | func CallIssueSshCredsV1(httpClient *resty.Client, request IssueSshCredsV1Request) (IssueSshCredsV1Response, error) {
11 | issueSshCredsResponse := IssueSshCredsV1Response{}
12 |
13 | res, err := httpClient.R().
14 | SetResult(&issueSshCredsResponse).
15 | SetBody(request).
16 | Post("/v1/ssh/certificates/issue")
17 |
18 | if err != nil {
19 | return IssueSshCredsV1Response{}, errors.NewRequestError(callIssueSshCredsOperation, err)
20 | }
21 |
22 | if res.IsError() {
23 | return IssueSshCredsV1Response{}, errors.NewAPIErrorWithResponse(callIssueSshCredsOperation, res)
24 | }
25 |
26 | return issueSshCredsResponse, nil
27 | }
28 |
--------------------------------------------------------------------------------
/packages/api/ssh/issue_ssh_host_host_cert.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callIssueSshHostHostCertOperation = "CallIssueSshHostHostCertV1"
11 |
12 | func CallIssueSshHostHostCertV1(httpClient *resty.Client, sshHostId string, body IssueSshHostHostCertV1Request) (IssueSshHostHostCertV1Response, error) {
13 | resp := IssueSshHostHostCertV1Response{}
14 |
15 | res, err := httpClient.R().
16 | SetBody(body).
17 | SetResult(&resp).
18 | Post(fmt.Sprintf("/v1/ssh/hosts/%s/issue-host-cert", sshHostId))
19 |
20 | if err != nil {
21 | return IssueSshHostHostCertV1Response{}, errors.NewRequestError(callIssueSshHostHostCertOperation, err)
22 | }
23 |
24 | if res.IsError() {
25 | return IssueSshHostHostCertV1Response{}, errors.NewAPIErrorWithResponse(callIssueSshHostHostCertOperation, res)
26 | }
27 |
28 | return resp, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/ssh/issue_ssh_host_user_cert.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/errors"
8 | )
9 |
10 | const callIssueSshHostUserCertOperation = "CallIssueSshHostUserCertV1"
11 |
12 | func CallIssueSshHostUserCertV1(httpClient *resty.Client, sshHostId string, body IssueSshHostUserCertV1Request) (IssueSshHostUserCertV1Response, error) {
13 | resp := IssueSshHostUserCertV1Response{}
14 |
15 | res, err := httpClient.R().
16 | SetBody(body).
17 | SetResult(&resp).
18 | Post(fmt.Sprintf("/v1/ssh/hosts/%s/issue-user-cert", sshHostId))
19 |
20 | if err != nil {
21 | return IssueSshHostUserCertV1Response{}, errors.NewRequestError(callIssueSshHostUserCertOperation, err)
22 | }
23 |
24 | if res.IsError() {
25 | return IssueSshHostUserCertV1Response{}, errors.NewAPIErrorWithResponse(callIssueSshHostUserCertOperation, res)
26 | }
27 |
28 | return resp, nil
29 | }
30 |
--------------------------------------------------------------------------------
/packages/api/ssh/models.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/infisical/go-sdk/packages/util"
5 | )
6 |
7 | type SignSshPublicKeyV1Request struct {
8 | CertificateTemplateID string `json:"certificateTemplateId"`
9 | PublicKey string `json:"publicKey"`
10 | CertType util.SshCertType `json:"certType,omitempty"`
11 | Principals []string `json:"principals"`
12 | TTL string `json:"ttl,omitempty"`
13 | KeyID string `json:"keyId,omitempty"`
14 | }
15 |
16 | type SignSshPublicKeyV1Response struct {
17 | SerialNumber string `json:"serialNumber"`
18 | SignedKey string `json:"signedKey"`
19 | }
20 |
21 | type IssueSshCredsV1Request struct {
22 | CertificateTemplateID string `json:"certificateTemplateId"`
23 | KeyAlgorithm util.CertKeyAlgorithm `json:"keyAlgorithm,omitempty"`
24 | CertType util.SshCertType `json:"certType,omitempty"`
25 | Principals []string `json:"principals"`
26 | TTL string `json:"ttl,omitempty"`
27 | KeyID string `json:"keyId,omitempty"`
28 | }
29 |
30 | type IssueSshCredsV1Response struct {
31 | SerialNumber string `json:"serialNumber"`
32 | SignedKey string `json:"signedKey"`
33 | PrivateKey string `json:"privateKey"`
34 | PublicKey string `json:"publicKey"`
35 | KeyAlgorithm util.CertKeyAlgorithm `json:"keyAlgorithm"`
36 | }
37 |
38 | type GetSshHostsV1Request struct{}
39 |
40 | type AllowedPrincipals struct {
41 | Usernames []string `json:"usernames"`
42 | }
43 |
44 | type SshHostLoginMapping struct {
45 | LoginUser string `json:"loginUser"`
46 | AllowedPrincipals AllowedPrincipals `json:"allowedPrincipals"`
47 | }
48 |
49 | type SshHost struct {
50 | ID string `json:"id"`
51 | ProjectID string `json:"projectId"`
52 | Hostname string `json:"hostname"`
53 | Alias string `json:"alias,omitempty"`
54 | UserCertTtl string `json:"userCertTtl"`
55 | HostCertTtl string `json:"hostCertTtl"`
56 | UserSshCaId string `json:"userSshCaId"`
57 | HostSshCaId string `json:"hostSshCaId"`
58 | LoginMappings []SshHostLoginMapping `json:"loginMappings"`
59 | }
60 |
61 | type GetSshHostsV1Response []SshHost
62 |
63 | type IssueSshHostUserCertV1Request struct {
64 | LoginUser string `json:"loginUser"`
65 | }
66 |
67 | type IssueSshHostUserCertV1Response struct {
68 | SerialNumber string `json:"serialNumber"`
69 | SignedKey string `json:"signedKey"`
70 | PrivateKey string `json:"privateKey"`
71 | PublicKey string `json:"publicKey"`
72 | KeyAlgorithm util.CertKeyAlgorithm `json:"keyAlgorithm"`
73 | }
74 |
75 | type IssueSshHostHostCertV1Request struct {
76 | PublicKey string `json:"publicKey"`
77 | }
78 |
79 | type IssueSshHostHostCertV1Response struct {
80 | SerialNumber string `json:"serialNumber"`
81 | SignedKey string `json:"signedKey"`
82 | }
83 |
84 | type AddSshHostV1Request struct {
85 | ProjectID string `json:"projectId"`
86 | Hostname string `json:"hostname"`
87 | Alias string `json:"alias,omitempty"`
88 | UserCertTtl string `json:"userCertTtl,omitempty"`
89 | HostCertTtl string `json:"hostCertTtl,omitempty"`
90 | UserSshCaId string `json:"userSshCaId,omitempty"`
91 | HostSshCaId string `json:"hostSshCaId,omitempty"`
92 | LoginMappings []SshHostLoginMapping `json:"loginMappings,omitempty"`
93 | }
94 |
95 | type AddSshHostV1Response SshHost
96 |
--------------------------------------------------------------------------------
/packages/api/ssh/sign_ssh_public_key.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-resty/resty/v2"
5 | "github.com/infisical/go-sdk/packages/errors"
6 | )
7 |
8 | const callSignSshPublicKeyOperation = "CallSignSshPublicKeyV1"
9 |
10 | func CallSignSshPublicKeyV1(httpClient *resty.Client, request SignSshPublicKeyV1Request) (SignSshPublicKeyV1Response, error) {
11 | signSshPublicKeyResponse := SignSshPublicKeyV1Response{}
12 |
13 | res, err := httpClient.R().
14 | SetResult(&signSshPublicKeyResponse).
15 | SetBody(request).
16 | Post("/v1/ssh/certificates/sign")
17 |
18 | if err != nil {
19 | return SignSshPublicKeyV1Response{}, errors.NewRequestError(callSignSshPublicKeyOperation, err)
20 | }
21 |
22 | if res.IsError() {
23 | return SignSshPublicKeyV1Response{}, errors.NewAPIErrorWithResponse(callSignSshPublicKeyOperation, res)
24 | }
25 |
26 | return signSshPublicKeyResponse, nil
27 | }
28 |
--------------------------------------------------------------------------------
/packages/errors/api.go:
--------------------------------------------------------------------------------
1 | package errors
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-resty/resty/v2"
7 | "github.com/infisical/go-sdk/packages/util"
8 | )
9 |
10 | // APIError represents an error response from the API
11 | type APIError struct {
12 | Operation string `json:"operation"`
13 | Method string `json:"method"`
14 | URL string `json:"url"`
15 | StatusCode int `json:"statusCode"`
16 | ErrorMessage string `json:"message,omitempty"`
17 | ReqId string `json:"reqId,omitempty"`
18 | }
19 |
20 | func (e *APIError) Error() string {
21 | msg := fmt.Sprintf(
22 | "APIError: %s unsuccessful response [%v %v] [status-code=%v] [reqId=%v]",
23 | e.Operation,
24 | e.Method,
25 | e.URL,
26 | e.StatusCode,
27 | e.ReqId,
28 | )
29 |
30 | if e.ErrorMessage != "" {
31 | return fmt.Sprintf("%s [message=\"%s\"]", msg, e.ErrorMessage)
32 |
33 | }
34 |
35 | return msg
36 | }
37 |
38 | func NewAPIError(operation string, res *resty.Response) error {
39 | return &APIError{
40 | Operation: operation,
41 | Method: res.Request.Method,
42 | URL: res.Request.URL,
43 | StatusCode: res.StatusCode(),
44 | }
45 | }
46 |
47 | func NewAPIErrorWithResponse(operation string, res *resty.Response) error {
48 | errorMessage := util.TryParseErrorBody(res)
49 | reqId := util.TryExtractReqId(res)
50 |
51 | return &APIError{
52 | Operation: operation,
53 | Method: res.Request.Method,
54 | URL: res.Request.URL,
55 | StatusCode: res.StatusCode(),
56 | ErrorMessage: errorMessage,
57 | ReqId: reqId,
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/packages/errors/request.go:
--------------------------------------------------------------------------------
1 | package errors
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | // RequestError represents an error that occurred during an API request
8 | type RequestError struct {
9 | Operation string `json:"operation"`
10 | error error `json:"-"`
11 | }
12 |
13 | func (e *RequestError) Error() string {
14 | return fmt.Sprintf("%s: unable to complete api request [err=%s]", e.Operation, e.error)
15 | }
16 |
17 | func NewRequestError(operation string, err error) error {
18 | return &RequestError{
19 | Operation: operation,
20 | error: err,
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/packages/models/auth.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type TokenType string
4 |
5 | const (
6 | BEARER_TOKEN_TYPE TokenType = "Bearer"
7 | )
8 |
9 | type UniversalAuthCredential struct {
10 | ClientID string
11 | ClientSecret string
12 | }
13 |
14 | type AccessTokenCredential struct {
15 | AccessToken string
16 | }
17 |
18 | type GCPIDTokenCredential struct {
19 | IdentityID string
20 | }
21 |
22 | type GCPIAMCredential struct {
23 | IdentityID string
24 | ServiceAccountKeyFilePath string
25 | }
26 |
27 | type AWSIAMCredential struct {
28 | IdentityID string
29 | }
30 |
31 | type KubernetesCredential struct {
32 | IdentityID string
33 | ServiceAccountToken string
34 | }
35 |
36 | type AzureCredential struct {
37 | IdentityID string
38 | Resource string
39 | }
40 |
41 | type OIDCCredential struct {
42 | IdentityID string
43 | JWT string
44 | }
45 |
46 | type JWTCredential struct {
47 | IdentityID string
48 | JWT string
49 | }
50 |
--------------------------------------------------------------------------------
/packages/models/dynamic_secrets.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "time"
4 |
5 | type DynamicSecret struct {
6 | Id string `json:"id"`
7 | Name string `json:"name"`
8 | Type string `json:"type"`
9 | Version int `json:"number"`
10 | DefaultTTL string `json:"defaultTTL"`
11 | MaxTTL string `json:"maxTTL"`
12 | FolderID string `json:"folderId"`
13 | Status string `json:"status"`
14 | StatusDetails string `json:"statusDetails"`
15 | CreatedAt time.Time `json:"createdAt"`
16 | UpdatedAt time.Time `json:"updatedAt"`
17 | }
18 |
19 | type DynamicSecretLease struct {
20 | Id string `json:"id"`
21 | Type string `json:"type"`
22 | Version int `json:"number"`
23 | ExternalEntityId string `json:"externalEntityId"`
24 | ExpireAt time.Time `json:"expireAt"`
25 | Status string `json:"status"`
26 | DynamicSecretId string `json:"dynamicSecretId"`
27 | StatusDetails string `json:"statusDetails"`
28 | CreatedAt time.Time `json:"createdAt"`
29 | UpdatedAt time.Time `json:"updatedAt"`
30 | }
31 |
32 | type DynamicSecretLeaseWithDynamicSecret struct {
33 | Id string `json:"id"`
34 | Type string `json:"type"`
35 | Version int `json:"number"`
36 | ExternalEntityId string `json:"externalEntityId"`
37 | ExpireAt time.Time `json:"expireAt"`
38 | Status string `json:"status"`
39 | DynamicSecretId string `json:"dynamicSecretId"`
40 | StatusDetails string `json:"statusDetails"`
41 | CreatedAt time.Time `json:"createdAt"`
42 | UpdatedAt time.Time `json:"updatedAt"`
43 | DynamicSecret DynamicSecret `json:"dynamicSecret"`
44 | }
45 |
--------------------------------------------------------------------------------
/packages/models/folders.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "time"
4 |
5 | type Folder struct {
6 | ID string `json:"id"`
7 | Name string `json:"name"`
8 | Version int `json:"version"`
9 | CreatedAt time.Time `json:"createdAt"`
10 | UpdatedAt time.Time `json:"updatedAt"`
11 | EnvironmentID string `json:"envId"`
12 | ParentID string `json:"parentId"`
13 | IsReserved bool `json:"isReserved"`
14 | }
15 |
--------------------------------------------------------------------------------
/packages/models/secrets.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type SecretMetadata struct {
4 | Key string `json:"key"`
5 | Value string `json:"value"`
6 | }
7 |
8 | type Secret struct {
9 | ID string `json:"id"`
10 | Workspace string `json:"workspace"`
11 | Environment string `json:"environment"`
12 | Version int `json:"version"`
13 | Type string `json:"type"`
14 | SecretKey string `json:"secretKey"`
15 | SecretValue string `json:"secretValue"`
16 | SecretComment string `json:"secretComment"`
17 | SecretPath string `json:"secretPath,omitempty"`
18 | SecretMetadata []SecretMetadata `json:"secretMetadata"`
19 | }
20 |
21 | type SecretImport struct {
22 | SecretPath string `json:"secretPath"`
23 | Environment string `json:"environment"`
24 | FolderID string `json:"folderId"`
25 | Secrets []Secret `json:"secrets"`
26 | }
27 |
--------------------------------------------------------------------------------
/packages/util/auth.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "fmt"
7 | "net/url"
8 | "os"
9 | "time"
10 |
11 | credentials "cloud.google.com/go/iam/credentials/apiv1"
12 | "cloud.google.com/go/iam/credentials/apiv1/credentialspb"
13 | "github.com/aws/aws-sdk-go-v2/aws"
14 | "github.com/aws/aws-sdk-go-v2/config"
15 | "github.com/go-resty/resty/v2"
16 | "google.golang.org/api/option"
17 | )
18 |
19 | func GetKubernetesServiceAccountToken(serviceAccountTokenPath string) (string, error) {
20 |
21 | if serviceAccountTokenPath == "" {
22 | serviceAccountTokenPath = DEFAULT_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH
23 | }
24 |
25 | token, err := os.ReadFile(serviceAccountTokenPath)
26 |
27 | if err != nil {
28 | return "", err
29 | }
30 |
31 | return string(token), nil
32 |
33 | }
34 |
35 | func buildAzureMetadataServiceURL(resource string) string {
36 | if resource != "" {
37 | return AZURE_METADATA_SERVICE_URL + url.PathEscape(resource)
38 | }
39 | return AZURE_METADATA_SERVICE_URL + AZURE_DEFAULT_RESOURCE
40 | }
41 |
42 | func GetAzureMetadataToken(httpClient *resty.Client, customResource string) (string, error) {
43 |
44 | type AzureMetadataResponse struct {
45 | AccessToken string `json:"access_token"`
46 | }
47 |
48 | metadataResponse := AzureMetadataResponse{}
49 |
50 | response, err := httpClient.R().
51 | SetResult(&metadataResponse).
52 | SetHeader("Metadata", "true").
53 | SetHeader("Accept", "application/json").
54 | Get(buildAzureMetadataServiceURL(customResource))
55 |
56 | if err != nil {
57 | return "", err
58 | }
59 |
60 | if response.IsError() {
61 | return "", fmt.Errorf("GetAzureMetadataToken: Unsuccessful response [%v %v] [status-code=%v] [Error: %s]", response.Request.Method, response.Request.URL, response.StatusCode(), TryParseErrorBody(response))
62 | }
63 |
64 | return metadataResponse.AccessToken, nil
65 | }
66 |
67 | func GetGCPMetadataToken(httpClient *resty.Client, identityID string) (string, error) {
68 |
69 | res, err := httpClient.R().
70 | SetHeader("Metadata-Flavor", "Google").
71 | Get(fmt.Sprintf("http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=%s&format=full", identityID))
72 |
73 | if err != nil {
74 | return "", err
75 | }
76 |
77 | if res.IsError() {
78 | return "", fmt.Errorf("GetGCPMetadataToken: Unsuccessful response [%v %v] [status-code=%v] [Error: %s]", res.Request.Method, res.Request.URL, res.StatusCode(), TryParseErrorBody(res))
79 | }
80 |
81 | return res.String(), nil
82 |
83 | }
84 |
85 | func GetAwsEC2IdentityDocumentRegion(timeout int) (string, error) {
86 |
87 | type AwsIdentityDocument struct {
88 | Region string `json:"region"`
89 | }
90 |
91 | httpClient := resty.New().SetTimeout(time.Duration(timeout) * time.Millisecond)
92 |
93 | res, err := httpClient.R().
94 | SetHeader("X-aws-ec2-metadata-token-ttl-seconds", "21600").
95 | Put(AWS_EC2_METADATA_TOKEN_URL)
96 |
97 | if err != nil {
98 | return "", err
99 | }
100 |
101 | if res.IsError() {
102 | return "", fmt.Errorf("GetAwsEC2IdentityDocumentRegion: Unsuccessful response [%v %v] [status-code=%v] [Error: %s]", res.Request.Method, res.Request.URL, res.StatusCode(), TryParseErrorBody(res))
103 | }
104 |
105 | metadataToken := res.String()
106 |
107 | res, err = httpClient.R().
108 | SetHeader("X-aws-ec2-metadata-token", metadataToken).
109 | SetHeader("Accept", "application/json").
110 | Get(AWS_EC2_INSTANCE_IDENTITY_DOCUMENT_URL)
111 |
112 | if err != nil {
113 | return "", err
114 | }
115 |
116 | if res.IsError() {
117 | return "", fmt.Errorf("GetAwsEC2IdentityDocumentRegion: Unsuccessful response [%v %v] [status-code=%v] [Error: %s]", res.Request.Method, res.Request.URL, res.StatusCode(), TryParseErrorBody(res))
118 | }
119 |
120 | // For some reason using .SetResult(&AwsIdentityDocument{}) doesn't work and just results in an empty object. This works though..
121 | var identityDocument AwsIdentityDocument
122 | err = json.Unmarshal(res.Body(), &identityDocument)
123 | if err != nil {
124 | return "", err
125 | }
126 |
127 | return identityDocument.Region, nil
128 |
129 | }
130 |
131 | func GetGCPIamServiceAccountToken(identityID string, serviceAccountKeyPath string) (string, error) {
132 |
133 | type JwtPayload struct {
134 | Sub string `json:"sub"`
135 | Aud string `json:"aud"`
136 | }
137 |
138 | ctx := context.Background()
139 |
140 | serviceAccountKey, err := os.ReadFile(serviceAccountKeyPath)
141 | if err != nil {
142 | return "", err
143 | }
144 |
145 | var creds map[string]string
146 | if err := json.Unmarshal(serviceAccountKey, &creds); err != nil {
147 | return "", fmt.Errorf("failed to unmarshal service account key: %v", err)
148 | }
149 |
150 | clientEmail := creds["client_email"]
151 | if clientEmail == "" {
152 | return "", fmt.Errorf("client email not found in service account key")
153 | }
154 |
155 | payload := JwtPayload{
156 | Sub: clientEmail,
157 | Aud: identityID,
158 | }
159 |
160 | payloadJSON, err := json.Marshal(payload)
161 | if err != nil {
162 | return "", fmt.Errorf("failed to marshal JWT payload: %v", err)
163 | }
164 |
165 | iamCredentialsClient, err := credentials.NewIamCredentialsClient(ctx, option.WithCredentialsFile(serviceAccountKeyPath))
166 | if err != nil {
167 | return "", fmt.Errorf("failed to create IAM credentials client: %v", err)
168 | }
169 |
170 | defer iamCredentialsClient.Close()
171 |
172 | signJwtRequest := &credentialspb.SignJwtRequest{
173 | Name: fmt.Sprintf("projects/-/serviceAccounts/%s", clientEmail),
174 | Payload: string(payloadJSON),
175 | }
176 |
177 | resp, err := iamCredentialsClient.SignJwt(ctx, signJwtRequest)
178 | if err != nil {
179 | return "", fmt.Errorf("failed to sign JWT: %v. Ensure the IAM Service Account Credentials API is enabled", err)
180 | }
181 |
182 | signedJwt := resp.SignedJwt
183 | if signedJwt == "" {
184 | return "", fmt.Errorf("failed to sign JWT: signedJwt is empty")
185 | }
186 |
187 | return signedJwt, nil
188 |
189 | }
190 |
191 | func GetAwsRegion() (string, error) {
192 | // in Lambda environments, the region is available in the AWS_REGION environment variable
193 | region := os.Getenv("AWS_REGION")
194 |
195 | if region != "" {
196 | return region, nil
197 | }
198 |
199 | // in EC2 environments, the region is available in the identity doc
200 |
201 | region, err := GetAwsEC2IdentityDocumentRegion(5000)
202 |
203 | if err != nil {
204 | return "", err
205 | }
206 |
207 | return region, nil
208 |
209 | }
210 |
211 | func RetrieveAwsCredentials() (credentials aws.Credentials, region string, err error) {
212 | presetAwsCfg, err := config.LoadDefaultConfig(context.TODO())
213 |
214 | if err == nil && presetAwsCfg.Region != "" {
215 | creds, err := presetAwsCfg.Credentials.Retrieve(context.TODO())
216 | if err == nil {
217 | return creds, presetAwsCfg.Region, nil
218 | }
219 | }
220 |
221 | awsRegion, err := GetAwsRegion()
222 | if err != nil {
223 | return aws.Credentials{}, "", err
224 | }
225 |
226 | awsCfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(awsRegion))
227 | if err != nil {
228 | return aws.Credentials{}, "", fmt.Errorf("unable to load SDK config, %v", err)
229 | }
230 |
231 | creds, err := awsCfg.Credentials.Retrieve(context.TODO())
232 | if err != nil {
233 | return aws.Credentials{}, "", fmt.Errorf("error retrieving credentials: %v", err)
234 | }
235 |
236 | return creds, awsRegion, nil
237 | }
238 |
--------------------------------------------------------------------------------
/packages/util/constants.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "context"
5 | "errors"
6 | )
7 |
8 | // Auth related:
9 | const (
10 |
11 | // Universal auth:
12 | INFISICAL_UNIVERSAL_AUTH_CLIENT_ID_ENV_NAME = "INFISICAL_UNIVERSAL_AUTH_CLIENT_ID"
13 | INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET_ENV_NAME = "INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET"
14 |
15 | // GCP auth:
16 | INFISICAL_GCP_AUTH_IDENTITY_ID_ENV_NAME = "INFISICAL_GCP_AUTH_IDENTITY_ID"
17 | INFISICAL_GCP_IAM_SERVICE_ACCOUNT_KEY_FILE_PATH_ENV_NAME = "INFISICAL_GCP_IAM_SERVICE_ACCOUNT_KEY_FILE_PATH"
18 |
19 | // AWS auth:
20 | INFISICAL_AWS_IAM_AUTH_IDENTITY_ID_ENV_NAME = "INFISICAL_AWS_IAM_AUTH_IDENTITY_ID"
21 |
22 | // Azure auth:
23 | INFISICAL_AZURE_AUTH_IDENTITY_ID_ENV_NAME = "INFISICAL_AZURE_AUTH_IDENTITY_ID"
24 |
25 | // Kubernetes auth:
26 | INFISICAL_KUBERNETES_IDENTITY_ID_ENV_NAME = "INFISICAL_KUBERNETES_IDENTITY_ID"
27 | INFISICAL_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH_ENV_NAME = "INFISICAL_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH"
28 |
29 | // OIDC auth:
30 | INFISICAL_OIDC_AUTH_IDENTITY_ID_ENV_NAME = "INFISICAL_OIDC_AUTH_IDENTITY_ID"
31 |
32 | // Access token:
33 | INFISICAL_ACCESS_TOKEN_ENV_NAME = "INFISICAL_ACCESS_TOKEN"
34 |
35 | // AWS metadata service:
36 | AWS_EC2_METADATA_TOKEN_URL = "http://169.254.169.254/latest/api/token"
37 | AWS_EC2_INSTANCE_IDENTITY_DOCUMENT_URL = "http://169.254.169.254/latest/dynamic/instance-identity/document"
38 |
39 | // Azure metadata service:
40 | AZURE_METADATA_SERVICE_URL = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=" // End of the URL needs to be appended with the resource
41 | AZURE_DEFAULT_RESOURCE = "https%3A%2F%2Fmanagement.azure.com/"
42 | )
43 |
44 | type AuthMethod string
45 |
46 | const (
47 | ACCESS_TOKEN AuthMethod = "ACCESS_TOKEN"
48 | UNIVERSAL_AUTH AuthMethod = "UNIVERSAL_AUTH"
49 | GCP_ID_TOKEN AuthMethod = "GCP_ID_TOKEN"
50 | GCP_IAM AuthMethod = "GCP_IAM"
51 | AWS_IAM AuthMethod = "AWS_IAM"
52 | KUBERNETES AuthMethod = "KUBERNETES"
53 | AZURE AuthMethod = "AZURE"
54 | OIDC_AUTH AuthMethod = "OIDC_AUTH"
55 | JWT_AUTH AuthMethod = "JWT_AUTH"
56 | )
57 |
58 | // SSH related:
59 | type CertKeyAlgorithm string
60 |
61 | const (
62 | RSA2048 CertKeyAlgorithm = "RSA_2048"
63 | RSA4096 CertKeyAlgorithm = "RSA_4096"
64 | ECDSAP256 CertKeyAlgorithm = "EC_prime256v1"
65 | ECDSAP384 CertKeyAlgorithm = "EC_secp384r1"
66 | )
67 |
68 | type SshCertType string
69 |
70 | const (
71 | UserCert SshCertType = "user"
72 | HostCert SshCertType = "host"
73 | )
74 |
75 | // General:
76 | const (
77 | DEFAULT_INFISICAL_API_URL = "https://app.infisical.com/api"
78 | DEFAULT_KUBERNETES_SERVICE_ACCOUNT_TOKEN_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/token"
79 | )
80 |
81 | var ErrContextCanceled = errors.New("context canceled")
82 | var ErrContextDeadlineExceeded error = context.DeadlineExceeded
83 |
--------------------------------------------------------------------------------
/packages/util/helper.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "context"
5 | "crypto/sha256"
6 | "encoding/hex"
7 | "encoding/json"
8 | "fmt"
9 | "os"
10 | "sort"
11 | "strings"
12 | "time"
13 |
14 | "github.com/go-resty/resty/v2"
15 | "github.com/infisical/go-sdk/packages/models"
16 | )
17 |
18 | func AppendAPIEndpoint(siteUrl string) string {
19 | // Ensure the address does not already end with "/api"
20 | if strings.HasSuffix(siteUrl, "/api") {
21 | return siteUrl
22 | }
23 |
24 | // Check if the address ends with a slash and append accordingly
25 | if siteUrl[len(siteUrl)-1] == '/' {
26 | return siteUrl + "api"
27 | }
28 | return siteUrl + "/api"
29 | }
30 |
31 | func PrintWarning(message string) {
32 | fmt.Fprintf(os.Stderr, "[Infisical] Warning: %v \n", message)
33 | }
34 |
35 | func EnsureUniqueSecretsByKey(secrets *[]models.Secret) {
36 | secretMap := make(map[string]models.Secret)
37 |
38 | // Move secrets to a map to ensure uniqueness
39 | for _, secret := range *secrets {
40 | secretMap[secret.SecretKey] = secret // Maps will overwrite existing entry with the same key
41 | }
42 |
43 | // Clear the slice
44 | *secrets = (*secrets)[:0]
45 |
46 | // Refill the slice from the map
47 | for _, secret := range secretMap {
48 | *secrets = append(*secrets, secret)
49 | }
50 | }
51 |
52 | // containsSecret checks if the given key exists in the slice of secrets
53 | func ContainsSecret(secrets []models.Secret, key string) bool {
54 | for _, secret := range secrets {
55 | if secret.SecretKey == key {
56 | return true
57 | }
58 | }
59 | return false
60 | }
61 |
62 | // Helper function to sort the secrets by key so we can create a consistent output
63 | func SortSecretsByKeys(secrets []models.Secret) []models.Secret {
64 | sort.Slice(secrets, func(i, j int) bool {
65 | return secrets[i].SecretKey < secrets[j].SecretKey
66 | })
67 | return secrets
68 | }
69 |
70 | /*
71 | If the status code is 400, there will most likely always be a body.
72 | The body is a json object with a message key. we need to try to parse it, but if it fails, we can just return an empty string.
73 | But if the status code is 500, there may not be a body. if there is, it will be a json object with a message key. we need to try to parse it, but if it fails, we can just return an empty string
74 | */
75 | func TryParseErrorBody(res *resty.Response) string {
76 | if res == nil || !res.IsError() {
77 | return ""
78 | }
79 |
80 | body := res.String()
81 | if body == "" {
82 | return ""
83 | }
84 |
85 | type ErrorResponse struct {
86 | Message string `json:"message"`
87 | ReqId string `json:"reqId"`
88 | }
89 |
90 | // stringify zod body entirely
91 | if res.StatusCode() == 422 {
92 | return body
93 | }
94 |
95 | // now we have a string, we need to try to parse it as json
96 | var errorResponse ErrorResponse
97 | err := json.Unmarshal([]byte(body), &errorResponse)
98 |
99 | if err != nil {
100 | return ""
101 | }
102 |
103 | return errorResponse.Message
104 | }
105 |
106 | func TryExtractReqId(res *resty.Response) string {
107 | if res == nil || !res.IsError() {
108 | return ""
109 | }
110 |
111 | type ErrorResponse struct {
112 | ReqId string `json:"reqId"`
113 | }
114 |
115 | var errorResponse ErrorResponse
116 |
117 | err := json.Unmarshal([]byte(res.String()), &errorResponse)
118 |
119 | if err != nil {
120 | return ""
121 | }
122 |
123 | return errorResponse.ReqId
124 | }
125 |
126 | func SleepWithContext(ctx context.Context, duration time.Duration) error {
127 | select {
128 | case <-ctx.Done():
129 | return ctx.Err()
130 | case <-time.After(duration):
131 | return nil
132 | }
133 | }
134 |
135 | func ComputeCacheKeyFromBytes(bytes []byte, feature string) string {
136 | key := sha256.Sum256(bytes)
137 | return fmt.Sprintf("%s-%s", feature, hex.EncodeToString(key[:]))
138 | }
139 |
--------------------------------------------------------------------------------
/resources/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/secrets.go:
--------------------------------------------------------------------------------
1 | package infisical
2 |
3 | import (
4 | "os"
5 |
6 | api "github.com/infisical/go-sdk/packages/api/secrets"
7 | "github.com/infisical/go-sdk/packages/models"
8 | "github.com/infisical/go-sdk/packages/util"
9 | )
10 |
11 | type ListSecretsOptions = api.ListSecretsV3RawRequest
12 | type RetrieveSecretOptions = api.RetrieveSecretV3RawRequest
13 | type UpdateSecretOptions = api.UpdateSecretV3RawRequest
14 | type CreateSecretOptions = api.CreateSecretV3RawRequest
15 | type DeleteSecretOptions = api.DeleteSecretV3RawRequest
16 |
17 | type BatchCreateSecret = api.BatchCreateSecret
18 | type SecretMetadata = models.SecretMetadata
19 |
20 | type BatchCreateSecretsOptions = api.BatchCreateSecretsV3RawRequest
21 |
22 | type BatchSecretsInterface interface {
23 | Create(options BatchCreateSecretsOptions) ([]models.Secret, error)
24 | }
25 |
26 | type SecretsInterface interface {
27 | List(options ListSecretsOptions) ([]models.Secret, error)
28 | Retrieve(options RetrieveSecretOptions) (models.Secret, error)
29 | Update(options UpdateSecretOptions) (models.Secret, error)
30 | Create(options CreateSecretOptions) (models.Secret, error)
31 | Delete(options DeleteSecretOptions) (models.Secret, error)
32 | Batch() BatchSecretsInterface
33 | }
34 |
35 | type Secrets struct {
36 | client *InfisicalClient
37 | }
38 |
39 | type BatchSecrets struct {
40 | client *InfisicalClient
41 | }
42 |
43 | func (s *Secrets) List(options ListSecretsOptions) ([]models.Secret, error) {
44 | res, err := api.CallListSecretsV3(s.client.cache, s.client.httpClient, options)
45 |
46 | if err != nil {
47 | return nil, err
48 | }
49 |
50 | if options.Recursive {
51 | util.EnsureUniqueSecretsByKey(&res.Secrets)
52 | }
53 |
54 | secrets := append([]models.Secret(nil), res.Secrets...) // Clone main secrets slice, we will modify this if imports are enabled
55 | if options.IncludeImports {
56 |
57 | // Append secrets from imports
58 | for _, importBlock := range res.Imports {
59 | for _, importSecret := range importBlock.Secrets {
60 | // Only append the secret if it is not already in the list, imports take precedence
61 | if !util.ContainsSecret(secrets, importSecret.SecretKey) {
62 | secrets = append(secrets, importSecret)
63 | }
64 | }
65 | }
66 | }
67 |
68 | if options.AttachToProcessEnv {
69 | for _, secret := range secrets {
70 | // Only set the environment variable if it is not already set
71 | if os.Getenv(secret.SecretKey) == "" {
72 | os.Setenv(secret.SecretKey, secret.SecretValue)
73 | }
74 | }
75 |
76 | }
77 |
78 | return util.SortSecretsByKeys(secrets), nil
79 | }
80 |
81 | func (s *Secrets) Retrieve(options RetrieveSecretOptions) (models.Secret, error) {
82 | res, err := api.CallRetrieveSecretV3(s.client.cache, s.client.httpClient, options)
83 |
84 | if err != nil {
85 | return models.Secret{}, err
86 | }
87 |
88 | return res.Secret, nil
89 | }
90 |
91 | func (s *Secrets) Update(options UpdateSecretOptions) (models.Secret, error) {
92 | res, err := api.CallUpdateSecretV3(s.client.httpClient, options)
93 |
94 | if err != nil {
95 | return models.Secret{}, err
96 | }
97 |
98 | return res.Secret, nil
99 | }
100 |
101 | func (s *Secrets) Create(options CreateSecretOptions) (models.Secret, error) {
102 | res, err := api.CallCreateSecretV3(s.client.httpClient, options)
103 |
104 | if err != nil {
105 | return models.Secret{}, err
106 | }
107 |
108 | return res.Secret, nil
109 | }
110 |
111 | func (s *Secrets) Delete(options DeleteSecretOptions) (models.Secret, error) {
112 | res, err := api.CallDeleteSecretV3(s.client.httpClient, options)
113 |
114 | if err != nil {
115 | return models.Secret{}, err
116 | }
117 |
118 | return res.Secret, nil
119 | }
120 |
121 | // Batch operations
122 |
123 | func (bs *BatchSecrets) Create(options BatchCreateSecretsOptions) ([]models.Secret, error) {
124 | res, err := api.CallBatchCreateSecretV3(bs.client.httpClient, options)
125 |
126 | if err != nil {
127 | return nil, err
128 | }
129 |
130 | return res.Secrets, nil
131 | }
132 |
133 | func (s *Secrets) Batch() BatchSecretsInterface {
134 | return &BatchSecrets{client: s.client}
135 | }
136 |
137 | func NewSecrets(client *InfisicalClient) SecretsInterface {
138 | return &Secrets{client: client}
139 | }
140 |
--------------------------------------------------------------------------------
/ssh.go:
--------------------------------------------------------------------------------
1 | package infisical
2 |
3 | import (
4 | api "github.com/infisical/go-sdk/packages/api/ssh"
5 | )
6 |
7 | type SignSshPublicKeyOptions = api.SignSshPublicKeyV1Request
8 | type IssueSshCredsOptions = api.IssueSshCredsV1Request
9 | type GetSshHostsOptions = api.GetSshHostsV1Request
10 | type IssueSshHostUserCertOptions = api.IssueSshHostUserCertV1Request
11 | type IssueSshHostHostCertOptions = api.IssueSshHostHostCertV1Request
12 | type AddSshHostOptions = api.AddSshHostV1Request
13 |
14 | type SshInterface interface {
15 | SignKey(options SignSshPublicKeyOptions) (api.SignSshPublicKeyV1Response, error)
16 | IssueCredentials(options IssueSshCredsOptions) (api.IssueSshCredsV1Response, error)
17 | GetSshHosts(options GetSshHostsOptions) (api.GetSshHostsV1Response, error)
18 | GetSshHostUserCaPublicKey(sshHostId string) (string, error)
19 | GetSshHostHostCaPublicKey(sshHostId string) (string, error)
20 | IssueSshHostUserCert(sshHostId string, options IssueSshHostUserCertOptions) (api.IssueSshHostUserCertV1Response, error)
21 | IssueSshHostHostCert(sshHostId string, options IssueSshHostHostCertOptions) (api.IssueSshHostHostCertV1Response, error)
22 | AddSshHost(options AddSshHostOptions) (api.AddSshHostV1Response, error)
23 | }
24 |
25 | type Ssh struct {
26 | client *InfisicalClient
27 | }
28 |
29 | func (f *Ssh) SignKey(options SignSshPublicKeyOptions) (api.SignSshPublicKeyV1Response, error) {
30 | res, err := api.CallSignSshPublicKeyV1(f.client.httpClient, options)
31 |
32 | if err != nil {
33 | return api.SignSshPublicKeyV1Response{}, err
34 | }
35 |
36 | return res, nil
37 | }
38 |
39 | func (f *Ssh) IssueCredentials(options IssueSshCredsOptions) (api.IssueSshCredsV1Response, error) {
40 | res, err := api.CallIssueSshCredsV1(f.client.httpClient, options)
41 |
42 | if err != nil {
43 | return api.IssueSshCredsV1Response{}, err
44 | }
45 |
46 | return res, nil
47 | }
48 |
49 | func (f *Ssh) GetSshHosts(options GetSshHostsOptions) (api.GetSshHostsV1Response, error) {
50 | res, err := api.GetSshHostsV1(f.client.httpClient, options)
51 |
52 | if err != nil {
53 | return api.GetSshHostsV1Response{}, err
54 | }
55 |
56 | return res, nil
57 | }
58 |
59 | func (f *Ssh) GetSshHostUserCaPublicKey(sshHostId string) (string, error) {
60 | res, err := api.GetSshHostUserCaPublicKeyV1(f.client.httpClient, sshHostId)
61 |
62 | if err != nil {
63 | return "", err
64 | }
65 |
66 | return res, nil
67 | }
68 |
69 | func (f *Ssh) GetSshHostHostCaPublicKey(sshHostId string) (string, error) {
70 | res, err := api.GetSshHostHostCaPublicKeyV1(f.client.httpClient, sshHostId)
71 |
72 | if err != nil {
73 | return "", err
74 | }
75 |
76 | return res, nil
77 | }
78 |
79 | func (f *Ssh) IssueSshHostUserCert(sshHostId string, options IssueSshHostUserCertOptions) (api.IssueSshHostUserCertV1Response, error) {
80 | res, err := api.CallIssueSshHostUserCertV1(f.client.httpClient, sshHostId, options)
81 | if err != nil {
82 | return api.IssueSshHostUserCertV1Response{}, err
83 | }
84 | return res, nil
85 | }
86 |
87 | func (f *Ssh) IssueSshHostHostCert(sshHostId string, options IssueSshHostHostCertOptions) (api.IssueSshHostHostCertV1Response, error) {
88 | res, err := api.CallIssueSshHostHostCertV1(f.client.httpClient, sshHostId, options)
89 | if err != nil {
90 | return api.IssueSshHostHostCertV1Response{}, err
91 | }
92 | return res, nil
93 | }
94 |
95 | func (f *Ssh) AddSshHost(options AddSshHostOptions) (api.AddSshHostV1Response, error) {
96 | res, err := api.CallAddSshHostV1(f.client.httpClient, options)
97 | if err != nil {
98 | return api.AddSshHostV1Response{}, err
99 | }
100 | return res, nil
101 | }
102 |
103 | func NewSsh(client *InfisicalClient) SshInterface {
104 | return &Ssh{client: client}
105 | }
106 |
--------------------------------------------------------------------------------
/test/aws_auth_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "testing"
7 |
8 | infisical "github.com/infisical/go-sdk"
9 | )
10 |
11 | func TestAWSAuthLogin(t *testing.T) {
12 |
13 | client := infisical.NewInfisicalClient(context.Background(), infisical.Config{
14 | SiteUrl: "https://c61b724baab4.ngrok.app",
15 | })
16 |
17 | accessToken, err := client.Auth().AwsIamAuthLogin("e2cddb75-a0e0-4c89-bfc0-4d536599f725") // test ID
18 |
19 | if err != nil {
20 | panic(err)
21 | }
22 |
23 | fmt.Println("Obtained access token: ", accessToken)
24 | }
25 |
--------------------------------------------------------------------------------
/test/kubernetes_auth_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | // import (
4 | // "testing"
5 |
6 | // infisical "github.com/infisical/go-sdk"
7 | // )
8 |
9 | // func TestKubernetesAuthLogin(t *testing.T) {
10 |
11 | // t.Skip("Skipping Kubernetes Auth test -- requires running in a Kubernetes cluster")
12 |
13 | // client, err := infisical.NewInfisicalClient(infisical.Config{
14 | // SiteUrl: "http://localhost:8080",
15 | // Auth: infisical.Authentication{
16 | // Kubernetes: infisical.KubernetesAuth{
17 | // IdentityID: "K8_MACHINE_IDENTITY_ID",
18 | // ServiceAccountTokenPath: "/var/run/secrets/kubernetes.io/serviceaccount/token", // Optional
19 | // },
20 | // },
21 | // })
22 |
23 | // // token1, err := client1.auth.kubernetesLogin(...)
24 | // // token2, err := client2.auth.kubernetesLogin(...)
25 |
26 | // // handle err
27 |
28 | // // client.auth.setToken(token)
29 |
30 | // if err != nil {
31 | // t.Fatalf("Failed to create Infisical client: %v", err)
32 | // }
33 |
34 | // secrets, err := client.Secrets().List(infisical.ListSecretsOptions{
35 | // ProjectID: "PROJECT_ID",
36 | // Environment: "ENV_SLUG",
37 | // })
38 |
39 | // if err != nil {
40 | // t.Fatalf("Failed to list secrets: %v", err)
41 | // }
42 |
43 | // if len(secrets) == 0 {
44 | // t.Fatalf("No secrets found")
45 | // }
46 |
47 | // t.Logf("Secrets: %v", secrets)
48 |
49 | // }
50 |
--------------------------------------------------------------------------------
/test/secrets_batch_create_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "context"
5 | "testing"
6 |
7 | infisical "github.com/infisical/go-sdk"
8 | )
9 |
10 | func TestBatchCreateSecrets(t *testing.T) {
11 | client := infisical.NewInfisicalClient(context.Background(), infisical.Config{
12 | SiteUrl: "http://localhost:8080",
13 | AutoTokenRefresh: true,
14 | })
15 |
16 | client.Auth().SetAccessToken("")
17 |
18 | secs, err := client.Secrets().Batch().Create(infisical.BatchCreateSecretsOptions{
19 | Environment: "dev",
20 | SecretPath: "/",
21 | ProjectID: "06c4d805-ac8a-456f-906f-1319554d15ec",
22 | Secrets: []infisical.BatchCreateSecret{
23 | {
24 | SecretKey: "test3",
25 | SecretValue: "test1",
26 | },
27 | {
28 | SecretKey: "test4",
29 | SecretValue: "test2",
30 | },
31 | },
32 | })
33 |
34 | if err != nil {
35 | t.Fatalf("Failed to create secrets: %v", err)
36 | }
37 |
38 | t.Logf("Secrets: %v", secs)
39 | }
40 |
--------------------------------------------------------------------------------
/test/ssh_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | // import (
4 | // "context"
5 | // "encoding/json"
6 | // "fmt"
7 | // "os"
8 | // "testing"
9 |
10 | // infisical "github.com/infisical/go-sdk"
11 | // )
12 |
13 | // func TestSshIssueCreds(t *testing.T) {
14 | // client := infisical.NewInfisicalClient(context.Background(), infisical.Config{
15 | // SiteUrl: "http://localhost:8080",
16 | // AutoTokenRefresh: true,
17 | // })
18 |
19 | // // Authenticate using Universal Auth
20 | // _, err := client.Auth().UniversalAuthLogin("", "")
21 | // if err != nil {
22 | // fmt.Printf("Authentication failed: %v\n", err)
23 | // os.Exit(1)
24 | // }
25 |
26 | // // Test adding SSH host
27 | // _, err = client.Ssh().AddSshHost(infisical.AddSshHostOptions{
28 | // ProjectID: "",
29 | // Hostname: "",
30 | // Alias: "",
31 | // })
32 | // if err != nil {
33 | // fmt.Printf("Failed to add SSH host: %v\n", err)
34 | // os.Exit(1)
35 | // }
36 |
37 | // // Test getting SSH hosts the user has access to
38 | // hosts, err := client.Ssh().GetSshHosts(infisical.GetSshHostsOptions{})
39 | // if err != nil {
40 | // t.Fatalf("Failed to fetch SSH hosts: %v", err)
41 | // }
42 |
43 | // if len(hosts) == 0 {
44 | // t.Fatalf("No SSH hosts returned")
45 | // }
46 |
47 | // fmt.Println("Got SSH hosts:")
48 | // for _, host := range hosts {
49 | // fmt.Printf("- Host: %s (ID: %s)\n", host.Hostname, host.ID)
50 | // }
51 |
52 | // // Test getting user CA public key for first host
53 | // userCaKey, err := client.Ssh().GetSshHostUserCaPublicKey(hosts[0].ID)
54 | // if err != nil {
55 | // t.Fatalf("Failed to get user CA public key: %v", err)
56 | // }
57 |
58 | // hostCaKey, err := client.Ssh().GetSshHostHostCaPublicKey(hosts[0].ID)
59 | // if err != nil {
60 | // t.Fatalf("Failed to get host CA public key: %v", err)
61 | // }
62 |
63 | // fmt.Printf("User CA Public Key for host %s:\n%s\n", hosts[0].Hostname, userCaKey)
64 |
65 | // for _, host := range hosts {
66 | // hostJson, err := json.MarshalIndent(host, "", " ")
67 | // if err != nil {
68 | // t.Errorf("Failed to marshal host %s: %v", host.ID, err)
69 | // continue
70 | // }
71 | // fmt.Println(string(hostJson))
72 | // }
73 |
74 | // // Pick the first host
75 | // targetHost := hosts[0]
76 |
77 | // // Test issuing SSH cert for user
78 | // creds, err := client.Ssh().IssueSshHostUserCert(targetHost.ID, infisical.IssueSshHostUserCertOptions{
79 | // LoginUser: "ec2-user", // or whatever login user is appropriate
80 | // })
81 | // if err != nil {
82 | // t.Fatalf("Failed to issue SSH credentials from host %s: %v", targetHost.ID, err)
83 | // }
84 |
85 | // // Display the credentials
86 | // credsJson, err := json.MarshalIndent(creds, "", " ")
87 | // if err != nil {
88 | // t.Fatalf("Failed to marshal issued credentials: %v", err)
89 | // }
90 | // fmt.Println("Issued user credentials:")
91 | // fmt.Println(string(credsJson))
92 |
93 | // // Test issuing SSH cert for host
94 | // creds2, err := client.Ssh().IssueSshHostHostCert(targetHost.ID, infisical.IssueSshHostHostCertOptions{
95 | // PublicKey: "",
96 | // })
97 | // if err != nil {
98 | // t.Fatalf("Failed to issue SSH credentials from host %s: %v", targetHost.ID, err)
99 | // }
100 |
101 | // // Display the credentials
102 | // creds2Json, err := json.MarshalIndent(creds2, "", " ")
103 | // if err != nil {
104 | // t.Fatalf("Failed to marshal issued credentials: %v", err)
105 | // }
106 | // fmt.Println("Issued credentials:")
107 | // fmt.Println(string(creds2Json))
108 |
109 | // // Test issuing SSH credentials
110 | // creds, err := client.Ssh().IssueCredentials(infisical.IssueSshCredsOptions{
111 | // CertificateTemplateID: "",
112 | // Principals: []string{"ec2-user"},
113 | // })
114 |
115 | // if err != nil {
116 | // t.Fatalf("Failed to issue SSH credentials: %v", err)
117 | // }
118 |
119 | // // Test signing SSH public key
120 | // creds2, err := client.Ssh().SignKey(infisical.SignSshPublicKeyOptions{
121 | // CertificateTemplateID: "",
122 | // Principals: []string{"ec2-user"},
123 | // PublicKey: "ssh-rsa ...",
124 | // })
125 |
126 | // if err != nil {
127 | // t.Fatalf("Failed to sign SSH public key: %v", err)
128 | // }
129 |
130 | // fmt.Print("Newly-issued SSH credentials: ", creds)
131 | // fmt.Print("Signed SSH credential: ", creds2)
132 | // }
133 |
--------------------------------------------------------------------------------
/test/universal_auth_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | // import (
4 | // "os"
5 | // "testing"
6 |
7 | // infisical "github.com/infisical/go-sdk"
8 | // )
9 |
10 | // func TestUniversalAuthLogin(t *testing.T) {
11 |
12 | // client, err := infisical.NewInfisicalClient(infisical.Config{
13 | // Auth: infisical.Authentication{
14 | // UniversalAuth: infisical.UniversalAuth{
15 | // ClientID: os.Getenv("GO_SDK_TEST_UNIVERSAL_AUTH_CLIENT_ID"),
16 | // ClientSecret: os.Getenv("GO_SDK_TEST_UNIVERSAL_AUTH_CLIENT_SECRET"),
17 | // },
18 | // },
19 | // })
20 |
21 | // if err != nil {
22 | // t.Fatalf("Failed to create Infisical client: %v", err)
23 | // }
24 |
25 | // secrets, err := client.Secrets().List(infisical.ListSecretsOptions{
26 | // ProjectID: os.Getenv("GO_SDK_TEST_PROJECT_ID"),
27 | // Environment: "dev",
28 | // })
29 |
30 | // if err != nil {
31 | // t.Fatalf("Failed to list secrets: %v", err)
32 | // }
33 |
34 | // if len(secrets) == 0 {
35 | // t.Fatalf("No secrets found")
36 | // }
37 |
38 | // t.Logf("Secrets: %v", secrets)
39 |
40 | // }
41 |
--------------------------------------------------------------------------------