Compare commits

...

8 Commits

Author SHA1 Message Date
b4689bed17 fix docs typo 2024-07-30 20:11:30 -04:00
bfd24ea938 Merge pull request #2204 from Infisical/maidul-dig2urdy3
add single secret fetch for agent
2024-07-30 20:09:32 -04:00
cea1a5e7ea add docs for single and list secrets functions for agent 2024-07-30 20:01:52 -04:00
8d32ca2fb6 Merge pull request #2205 from Infisical/vmatsiiako-docs-patch-1
Update migrating-from-envkey.mdx
2024-07-30 16:25:56 -07:00
d468067d43 Update migrating-from-envkey.mdx 2024-07-30 16:24:47 -07:00
3a640d6cf8 add single secret fetch for agent 2024-07-30 19:23:24 -04:00
8fc85105a9 Merge pull request #2203 from Infisical/secret-sharing-fix-padding
Add More Padding to Secret Sharing Banner
2024-07-30 13:49:29 -07:00
48bd354bae Add more padding for secret sharing promo banner 2024-07-30 13:46:40 -07:00
10 changed files with 142 additions and 12 deletions

View File

@ -434,6 +434,34 @@ func CallGetRawSecretsV3(httpClient *resty.Client, request GetRawSecretsV3Reques
return getRawSecretsV3Response, nil
}
func CallFetchSingleSecretByName(httpClient *resty.Client, request GetRawSecretV3ByNameRequest) (GetRawSecretV3ByNameResponse, error) {
var getRawSecretV3ByNameResponse GetRawSecretV3ByNameResponse
response, err := httpClient.
R().
SetHeader("User-Agent", USER_AGENT).
SetResult(&getRawSecretV3ByNameResponse).
SetBody(request).
SetQueryParam("expandSecretReferences", "true").
SetQueryParam("include_imports", "true").
SetQueryParam("environment", request.Environment).
SetQueryParam("secretPath", request.SecretPath).
SetQueryParam("workspaceId", request.WorkspaceID).
SetQueryParam("type", "shared").
Get(fmt.Sprintf("%v/v3/secrets/raw/%s", config.INFISICAL_URL, request.SecretName))
if err != nil {
return GetRawSecretV3ByNameResponse{}, fmt.Errorf("CallFetchSingleSecretByName: Unable to complete api request [err=%w]", err)
}
if response.IsError() {
return GetRawSecretV3ByNameResponse{}, fmt.Errorf("CallFetchSingleSecretByName: Unsuccessful response [%v %v] [status-code=%v] [response=%v]", response.Request.Method, response.Request.URL, response.StatusCode(), response.String())
}
getRawSecretV3ByNameResponse.ETag = response.Header().Get(("etag"))
return getRawSecretV3ByNameResponse, nil
}
func CallCreateDynamicSecretLeaseV1(httpClient *resty.Client, request CreateDynamicSecretLeaseV1Request) (CreateDynamicSecretLeaseV1Response, error) {
var createDynamicSecretLeaseResponse CreateDynamicSecretLeaseV1Response
response, err := httpClient.

View File

@ -590,3 +590,25 @@ type GetRawSecretsV3Response struct {
Imports []ImportedRawSecretV3 `json:"imports"`
ETag string
}
type GetRawSecretV3ByNameRequest struct {
SecretName string `json:"secretName"`
WorkspaceID string `json:"workspaceId"`
Type string `json:"type,omitempty"`
Environment string `json:"environment"`
SecretPath string `json:"secretPath,omitempty"`
}
type GetRawSecretV3ByNameResponse struct {
Secret struct {
ID string `json:"_id"`
Version int `json:"version"`
Workspace string `json:"workspace"`
Type string `json:"type"`
Environment string `json:"environment"`
SecretKey string `json:"secretKey"`
SecretValue string `json:"secretValue"`
SecretComment string `json:"secretComment"`
} `json:"secret"`
ETag string
}

View File

@ -327,6 +327,21 @@ func secretTemplateFunction(accessToken string, existingEtag string, currentEtag
}
}
func getSingleSecretTemplateFunction(accessToken string, existingEtag string, currentEtag *string) func(string, string, string, string) (models.SingleEnvironmentVariable, error) {
return func(projectID, envSlug, secretPath, secretName string) (models.SingleEnvironmentVariable, error) {
secret, requestEtag, err := util.GetSinglePlainTextSecretByNameV3(accessToken, projectID, envSlug, secretPath, secretName)
if err != nil {
return models.SingleEnvironmentVariable{}, err
}
if existingEtag != requestEtag {
*currentEtag = requestEtag
}
return secret, nil
}
}
func dynamicSecretTemplateFunction(accessToken string, dynamicSecretManager *DynamicSecretLeaseManager, templateId int) func(...string) (map[string]interface{}, error) {
return func(args ...string) (map[string]interface{}, error) {
argLength := len(args)
@ -358,9 +373,12 @@ func ProcessTemplate(templateId int, templatePath string, data interface{}, acce
// custom template function to fetch secrets from Infisical
secretFunction := secretTemplateFunction(accessToken, existingEtag, currentEtag)
dynamicSecretFunction := dynamicSecretTemplateFunction(accessToken, dynamicSecretManager, templateId)
getSingleSecretFunction := getSingleSecretTemplateFunction(accessToken, existingEtag, currentEtag)
funcs := template.FuncMap{
"secret": secretFunction,
"dynamic_secret": dynamicSecretFunction,
"secret": secretFunction, // depreciated
"listSecrets": secretFunction,
"dynamic_secret": dynamicSecretFunction,
"getSecretByName": getSingleSecretFunction,
"minus": func(a, b int) int {
return a - b
},

View File

@ -35,6 +35,7 @@ type SingleEnvironmentVariable struct {
Workspace string `json:"workspace"`
} `json:"tags"`
Comment string `json:"comment"`
Etag string `json:"Etag"`
}
type PlaintextSecretResult struct {

View File

@ -24,7 +24,7 @@ func ConvertPollingIntervalToTime(pollingInterval string) (time.Duration, error)
switch unit {
case "s":
if number < 60 {
return 0, fmt.Errorf("polling interval should be at least 60 seconds")
return 0, fmt.Errorf("polling interval must be at least 60 seconds")
}
return time.Duration(number) * time.Second, nil
case "m":

View File

@ -118,6 +118,36 @@ func GetPlainTextSecretsV3(accessToken string, workspaceId string, environmentNa
}, nil
}
func GetSinglePlainTextSecretByNameV3(accessToken string, workspaceId string, environmentName string, secretsPath string, secretName string) (models.SingleEnvironmentVariable, string, error) {
httpClient := resty.New()
httpClient.SetAuthToken(accessToken).
SetHeader("Accept", "application/json")
getSecretsRequest := api.GetRawSecretV3ByNameRequest{
WorkspaceID: workspaceId,
Environment: environmentName,
SecretName: secretName,
SecretPath: secretsPath,
}
rawSecret, err := api.CallFetchSingleSecretByName(httpClient, getSecretsRequest)
if err != nil {
return models.SingleEnvironmentVariable{}, "", err
}
formattedSecrets := models.SingleEnvironmentVariable{
Key: rawSecret.Secret.SecretKey,
WorkspaceId: rawSecret.Secret.Workspace,
Value: rawSecret.Secret.SecretValue,
Type: rawSecret.Secret.Type,
ID: rawSecret.Secret.ID,
Comment: rawSecret.Secret.SecretComment,
}
return formattedSecrets, rawSecret.ETag, nil
}
func CreateDynamicSecretLease(accessToken string, projectSlug string, environmentName string, secretsPath string, slug string, ttl string) (models.DynamicSecretLease, error) {
httpClient := resty.New()
httpClient.SetAuthToken(accessToken).

View File

@ -8,7 +8,7 @@ description: "Learn how to migrate from EnvKey to Infisical in the easiest way p
[Infisical](https://infisical.com) is an open-source all-in-one secret management platform that helps developers manage secrets (e.g., API-keys, DB access tokens, [certificates](https://infisical.com/docs/documentation/platform/pki/overview)) across their infrastructure. In addition, Infisical provides [secret sharing](https://infisical.com/docs/documentation/platform/secret-sharing) functionality, ability to [prevent secret leaks](https://infisical.com/docs/cli/scanning-overview), and more.
Infisical is used by 10,000+ organizations across all indsutries including First American Financial Corporation, Deivery Hero, and [Hugging Face](https://infisical.com/customers/hugging-face).
Infisical is used by 10,000+ organizations across all industries including First American Financial Corporation, Delivery Hero, and [Hugging Face](https://infisical.com/customers/hugging-face).
## Migrating from EnvKey

View File

@ -252,7 +252,7 @@ To install the Infisical agent, you must first install the [Infisical CLI](../cl
Once you have the CLI installed, you will need to provision programmatic access for the agent via [Universal Auth](/documentation/platform/identities/universal-auth). To obtain a **Client ID** and a **Client Secret**, follow the step by step guide outlined [here](/documentation/platform/identities/universal-auth).
Next, create agent config file as shown below.
Next, create agent config file as shown below. The example agent configuration file defines the token authentication method, one sink location, and a secret template.
```yaml example-agent-config-file.yaml
infisical:
@ -277,8 +277,8 @@ templates:
command: ./reload-app.sh
```
Above is an example agent configuration file that defines the token authentication method, one sink location (where to deposit access tokens after renewal) and a secret template.
The secret template below will be used to render the secrets with the key and the value separated by `=` sign. You'll notice that a custom function named `secret` is used to fetch the secrets.
This function takes the following arguments: `secret "<project-id>" "<environment-slug>" "<secret-path>"`.
```text my-dot-ev-secret-template
{{- with secret "6553ccb2b7da580d7f6e7260" "dev" "/" }}
@ -288,11 +288,42 @@ Above is an example agent configuration file that defines the token authenticati
{{- end }}
```
The secret template above will be used to render the secrets where the key and the value are separated by `=` sign. You'll notice that a custom function named `secret` is used to fetch the secrets.
This function takes the following arguments: `secret "<project-id>" "<environment-slug>" "<secret-path>"`.
After defining the agent configuration file, run the command below pointing to the path where the agent configuration file is located.
```bash
infisical agent --config example-agent-config-file.yaml
```
After defining the agent configuration file, run the command above pointing to the path where the agent configuration is located.
### Available secret template functions
<Accordion title="listSecrets">
```bash
listSecrets "<project-id>" "environment-slug" "<secret-path>"
```
```bash example-template-usage
{{- with listSecrets "6553ccb2b7da580d7f6e7260" "dev" "/" }}
{{- range . }}
{{ .Key }}={{ .Value }}
{{- end }}
{{- end }}
```
This function can be used to render the full list of secrets within a given project, environment and secret path.
</Accordion>
<Accordion title="getSecretByName">
```bash
getSecretByName "<project-id>" "<environment-slug>" "<secret-path>" "<secret-name>"
```
```bash example-template-usage
{{ with getSecretByName "d821f21d-aa90-453b-8448-8c78c1160a0e" "dev" "/" "POSTHOG_HOST"}}
{{ if .Value }}
password = "{{ .Value }}"
{{ end }}
{{ end }}
```
This function can be used to render a single secret by it's name.
</Accordion>

View File

@ -9,7 +9,7 @@ export const ShareSecretPublicPage = () => {
return (
<div className="flex h-screen flex-col justify-between overflow-auto bg-gradient-to-tr from-mineshaft-700 to-bunker-800 text-gray-200 dark:[color-scheme:dark]">
<div />
<div className="mx-auto w-full max-w-xl p-4">
<div className="mx-auto w-full max-w-xl px-4 py-4 md:px-0">
<div className="mb-8 text-center">
<div className="mb-4 flex justify-center pt-8">
<Link href="https://infisical.com">

View File

@ -24,7 +24,7 @@ export const ViewSecretPublicPage = () => {
return (
<div className="flex h-screen flex-col justify-between overflow-auto bg-gradient-to-tr from-mineshaft-700 to-bunker-800 text-gray-200 dark:[color-scheme:dark]">
<div />
<div className="mx-auto w-full max-w-xl p-4 ">
<div className="mx-auto w-full max-w-xl px-4 py-4 md:px-0">
<div className="mb-8 text-center">
<div className="mb-4 flex justify-center pt-8">
<Link href="https://infisical.com">