feat: added raw template for agent

This commit is contained in:
Sheen Capadngan
2024-08-24 01:48:39 +08:00
parent 68b1984a76
commit 8f79d3210a
3 changed files with 121 additions and 67 deletions
+14 -1
View File
@@ -11,12 +11,25 @@ sinks:
config: config:
path: "access-token" path: "access-token"
templates: templates:
- source-path: my-dot-ev-secret-template - template-content: |
{{- with secret "202f04d7-e4cb-43d4-a292-e893712d61fc" "dev" "/" }}
{{- range . }}
{{ .Key }}={{ .Value }}
{{- end }}
{{- end }}
destination-path: my-dot-env-0.env
config:
polling-interval: 60s
execute:
command: docker-compose -f docker-compose.prod.yml down && docker-compose -f docker-compose.prod.yml up -d
- base64-template-content: e3stIHdpdGggc2VjcmV0ICIyMDJmMDRkNy1lNGNiLTQzZDQtYTI5Mi1lODkzNzEyZDYxZmMiICJkZXYiICIvIiB9fQp7ey0gcmFuZ2UgLiB9fQp7eyAuS2V5IH19PXt7IC5WYWx1ZSB9fQp7ey0gZW5kIH19Cnt7LSBlbmQgfX0=
destination-path: my-dot-env.env destination-path: my-dot-env.env
config: config:
polling-interval: 60s polling-interval: 60s
execute: execute:
command: docker-compose -f docker-compose.prod.yml down && docker-compose -f docker-compose.prod.yml up -d command: docker-compose -f docker-compose.prod.yml down && docker-compose -f docker-compose.prod.yml up -d
- source-path: my-dot-ev-secret-template1 - source-path: my-dot-ev-secret-template1
destination-path: my-dot-env-1.env destination-path: my-dot-env-1.env
config: config:
+27
View File
@@ -95,6 +95,7 @@ type Template struct {
SourcePath string `yaml:"source-path"` SourcePath string `yaml:"source-path"`
Base64TemplateContent string `yaml:"base64-template-content"` Base64TemplateContent string `yaml:"base64-template-content"`
DestinationPath string `yaml:"destination-path"` DestinationPath string `yaml:"destination-path"`
TemplateContent string `yaml:"template-content"`
Config struct { // Configurations for the template Config struct { // Configurations for the template
PollingInterval string `yaml:"polling-interval"` // How often to poll for changes in the secret PollingInterval string `yaml:"polling-interval"` // How often to poll for changes in the secret
@@ -432,6 +433,30 @@ func ProcessBase64Template(templateId int, encodedTemplate string, data interfac
return &buf, nil return &buf, nil
} }
func ProcessLiteralTemplate(templateId int, templateString string, data interface{}, accessToken string, existingEtag string, currentEtag *string, dynamicSecretLeaser *DynamicSecretLeaseManager) (*bytes.Buffer, error) {
secretFunction := secretTemplateFunction(accessToken, existingEtag, currentEtag) // TODO: Fix this
dynamicSecretFunction := dynamicSecretTemplateFunction(accessToken, dynamicSecretLeaser, templateId)
funcs := template.FuncMap{
"secret": secretFunction,
"dynamic_secret": dynamicSecretFunction,
}
templateName := "literalTemplate"
tmpl, err := template.New(templateName).Funcs(funcs).Parse(templateString)
if err != nil {
return nil, err
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, data); err != nil {
return nil, err
}
return &buf, nil
}
type AgentManager struct { type AgentManager struct {
accessToken string accessToken string
accessTokenTTL time.Duration accessTokenTTL time.Duration
@@ -820,6 +845,8 @@ func (tm *AgentManager) MonitorSecretChanges(secretTemplate Template, templateId
if secretTemplate.SourcePath != "" { if secretTemplate.SourcePath != "" {
processedTemplate, err = ProcessTemplate(templateId, secretTemplate.SourcePath, nil, token, existingEtag, &currentEtag, tm.dynamicSecretLeases) processedTemplate, err = ProcessTemplate(templateId, secretTemplate.SourcePath, nil, token, existingEtag, &currentEtag, tm.dynamicSecretLeases)
} else if secretTemplate.TemplateContent != "" {
processedTemplate, err = ProcessLiteralTemplate(templateId, secretTemplate.TemplateContent, nil, token, existingEtag, &currentEtag, tm.dynamicSecretLeases)
} else { } else {
processedTemplate, err = ProcessBase64Template(templateId, secretTemplate.Base64TemplateContent, nil, token, existingEtag, &currentEtag, tm.dynamicSecretLeases) processedTemplate, err = ProcessBase64Template(templateId, secretTemplate.Base64TemplateContent, nil, token, existingEtag, &currentEtag, tm.dynamicSecretLeases)
} }
@@ -9,10 +9,12 @@ It eliminates the need to modify application logic by enabling clients to decide
![agent diagram](/images/agent/infisical-agent-diagram.png) ![agent diagram](/images/agent/infisical-agent-diagram.png)
### Key features: ### Key features:
- Token renewal: Automatically authenticates with Infisical and deposits renewed access tokens at specified path for applications to consume - Token renewal: Automatically authenticates with Infisical and deposits renewed access tokens at specified path for applications to consume
- Templating: Renders secrets via user provided templates to desired formats for applications to consume - Templating: Renders secrets via user provided templates to desired formats for applications to consume
### Token renewal ### Token renewal
The Infisical agent can help manage the life cycle of access tokens. The token renewal process is split into two main components: a `Method`, which is the authentication process suitable for your current setup, and `Sinks`, which are the places where the agent deposits the new access token whenever it receives updates. The Infisical agent can help manage the life cycle of access tokens. The token renewal process is split into two main components: a `Method`, which is the authentication process suitable for your current setup, and `Sinks`, which are the places where the agent deposits the new access token whenever it receives updates.
When the Infisical Agent is started, it will attempt to obtain a valid access token using the authentication method you have configured. If the agent is unable to fetch a valid token, the agent will keep trying, increasing the time between each attempt. When the Infisical Agent is started, it will attempt to obtain a valid access token using the authentication method you have configured. If the agent is unable to fetch a valid token, the agent will keep trying, increasing the time between each attempt.
@@ -22,10 +24,12 @@ Once a access token is successfully fetched, the agent will make sure the access
Every time the agent successfully retrieves a new access token, it writes the new token to the Sinks you've configured. Every time the agent successfully retrieves a new access token, it writes the new token to the Sinks you've configured.
<Info> <Info>
Access tokens can be utilized with Infisical SDKs or directly in API requests to retrieve secrets from Infisical Access tokens can be utilized with Infisical SDKs or directly in API requests
to retrieve secrets from Infisical
</Info> </Info>
### Templating ### Templating
The Infisical agent can help deliver formatted secrets to your application in a variety of environments. To achieve this, the agent will retrieve secrets from Infisical, format them using a specified template, and then save these formatted secrets to a designated file path. The Infisical agent can help deliver formatted secrets to your application in a variety of environments. To achieve this, the agent will retrieve secrets from Infisical, format them using a specified template, and then save these formatted secrets to a designated file path.
Templating process is done through the use of Go language's [text/template feature](https://pkg.go.dev/text/template). Multiple template definitions can be set in the agent configuration file to generate a variety of formatted secret files. Templating process is done through the use of Go language's [text/template feature](https://pkg.go.dev/text/template). Multiple template definitions can be set in the agent configuration file to generate a variety of formatted secret files.
@@ -42,7 +46,7 @@ To set up the authentication method for token renewal and to define secret templ
While specifying an authentication method is mandatory to start the agent, configuring sinks and secret templates are optional. While specifying an authentication method is mandatory to start the agent, configuring sinks and secret templates are optional.
| Field | Description | | Field | Description |
| ------------------------------------------------| ----------------------------- | | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `infisical.address` | The URL of the Infisical service. Default: `"https://app.infisical.com"`. | | `infisical.address` | The URL of the Infisical service. Default: `"https://app.infisical.com"`. |
| `auth.type` | The type of authentication method used. Available options: `universal-auth`, `kubernetes`, `azure`, `gcp-id-token`, `gcp-iam`, `aws-iam` | | `auth.type` | The type of authentication method used. Available options: `universal-auth`, `kubernetes`, `azure`, `gcp-id-token`, `gcp-iam`, `aws-iam` |
| `auth.config.identity-id` | The file path where the machine identity id is stored<br/><br/>This field is required when using any of the following auth types: `kubernetes`, `azure`, `gcp-id-token`, `gcp-iam`, or `aws-iam`. | | `auth.config.identity-id` | The file path where the machine identity id is stored<br/><br/>This field is required when using any of the following auth types: `kubernetes`, `azure`, `gcp-id-token`, `gcp-iam`, or `aws-iam`. |
@@ -54,12 +58,12 @@ While specifying an authentication method is mandatory to start the agent, confi
| `sinks[].type` | The type of sink in a list of sinks. Each item specifies a sink type. Currently, only `"file"` type is available. | | `sinks[].type` | The type of sink in a list of sinks. Each item specifies a sink type. Currently, only `"file"` type is available. |
| `sinks[].config.path` | The file path where the access token should be stored for each sink in the list. | | `sinks[].config.path` | The file path where the access token should be stored for each sink in the list. |
| `templates[].source-path` | The path to the template file that should be used to render secrets. | | `templates[].source-path` | The path to the template file that should be used to render secrets. |
| `templates[].template-content` | The format to use for rendering the secrets. |
| `templates[].destination-path` | The path where the rendered secrets from the source template will be saved to. | | `templates[].destination-path` | The path where the rendered secrets from the source template will be saved to. |
| `templates[].config.polling-interval` | How frequently to check for secret changes. Default: `5 minutes` (optional) | | `templates[].config.polling-interval` | How frequently to check for secret changes. Default: `5 minutes` (optional) |
| `templates[].config.execute.command` | The command to execute when secret change is detected (optional) | | `templates[].config.execute.command` | The command to execute when secret change is detected (optional) |
| `templates[].config.execute.timeout` | How long in seconds to wait for command to execute before timing out (optional) | | `templates[].config.execute.timeout` | How long in seconds to wait for command to execute before timing out (optional) |
## Authentication ## Authentication
The Infisical agent supports multiple authentication methods. Below are the available authentication methods, with their respective configurations. The Infisical agent supports multiple authentication methods. Below are the available authentication methods, with their respective configurations.
@@ -77,7 +81,8 @@ The Infisical agent supports multiple authentication methods. Below are the avai
Path to the file containing the universal auth client secret. Path to the file containing the universal auth client secret.
</ParamField> </ParamField>
<ParamField query="remove_client_secret_on_read" type="boolean" optional> <ParamField query="remove_client_secret_on_read" type="boolean" optional>
Instructs the agent to remove the client secret from disk after reading it. Instructs the agent to remove the client secret from disk after reading
it.
</ParamField> </ParamField>
</Expandable> </Expandable>
</ParamField> </ParamField>
@@ -98,18 +103,22 @@ The Infisical agent supports multiple authentication methods. Below are the avai
remove_client_secret_on_read: false # Optional field, instructs the agent to remove the client secret from disk after reading it remove_client_secret_on_read: false # Optional field, instructs the agent to remove the client secret from disk after reading it
``` ```
</Step> </Step>
</Steps> </Steps>
</Accordion> </Accordion>
<Accordion title="Native Kubernetes"> <Accordion title="Native Kubernetes">
The Native Kubernetes method is used to authenticate with Infisical when running in a Kubernetes environment. It requires a service account token to authenticate with Infisical. The Native Kubernetes method is used to authenticate with Infisical when running in a Kubernetes environment. It requires a service account token to authenticate with Infisical.
{" "}
<ParamField query="config" type="KubernetesAuthConfig"> <ParamField query="config" type="KubernetesAuthConfig">
<Expandable title="properties"> <Expandable title="properties">
<ParamField query="identity-id" type="string" required> <ParamField query="identity-id" type="string" required>
Path to the file containing the machine identity ID. Path to the file containing the machine identity ID.
</ParamField> </ParamField>
<ParamField query="service-account-token" type="string" optional> <ParamField query="service-account-token" type="string" optional>
Path to the Kubernetes service account token to use. Default: `/var/run/secrets/kubernetes.io/serviceaccount/token`. Path to the Kubernetes service account token to use. Default:
`/var/run/secrets/kubernetes.io/serviceaccount/token`.
</ParamField> </ParamField>
</Expandable> </Expandable>
</ParamField> </ParamField>
@@ -129,6 +138,7 @@ The Infisical agent supports multiple authentication methods. Below are the avai
service-account-token: "/var/run/secrets/kubernetes.io/serviceaccount/token" # Optional field, custom path to the Kubernetes service account token to use service-account-token: "/var/run/secrets/kubernetes.io/serviceaccount/token" # Optional field, custom path to the Kubernetes service account token to use
``` ```
</Step> </Step>
</Steps> </Steps>
</Accordion> </Accordion>
@@ -186,6 +196,7 @@ The Infisical agent supports multiple authentication methods. Below are the avai
``` ```
</Step> </Step>
</Steps> </Steps>
</Accordion> </Accordion>
<Accordion title="GCP IAM"> <Accordion title="GCP IAM">
The GCP IAM method is used to authenticate with Infisical with a GCP service account key. The GCP IAM method is used to authenticate with Infisical with a GCP service account key.
@@ -217,6 +228,7 @@ The Infisical agent supports multiple authentication methods. Below are the avai
``` ```
</Step> </Step>
</Steps> </Steps>
</Accordion> </Accordion>
<Accordion title="Native AWS IAM"> <Accordion title="Native AWS IAM">
The AWS IAM method is used to authenticate with Infisical with an AWS IAM role while running in an AWS environment like EC2, Lambda, etc. The AWS IAM method is used to authenticate with Infisical with an AWS IAM role while running in an AWS environment like EC2, Lambda, etc.
@@ -244,10 +256,12 @@ The Infisical agent supports multiple authentication methods. Below are the avai
``` ```
</Step> </Step>
</Steps> </Steps>
</Accordion> </Accordion>
</AccordionGroup> </AccordionGroup>
## Quick start Infisical Agent ## Quick start Infisical Agent
To install the Infisical agent, you must first install the [Infisical CLI](../cli/overview) in the desired environment where you'd like the agent to run. This is because the Infisical agent is a sub-command of the Infisical CLI. To install the Infisical agent, you must first install the [Infisical CLI](../cli/overview) in the desired environment where you'd like the agent to run. This is because the Infisical agent is a sub-command of the Infisical CLI.
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). 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).
@@ -290,13 +304,12 @@ This function takes the following arguments: `secret "<project-id>" "<environmen
After defining the agent configuration file, run the command below pointing to the path where the agent configuration file is located. After defining the agent configuration file, run the command below pointing to the path where the agent configuration file is located.
```bash ```bash
infisical agent --config example-agent-config-file.yaml infisical agent --config example-agent-config-file.yaml
``` ```
### Available secret template functions ### Available secret template functions
<Accordion title="listSecrets"> <Accordion title="listSecrets">
```bash ```bash
listSecrets "<project-id>" "environment-slug" "<secret-path>" listSecrets "<project-id>" "environment-slug" "<secret-path>"
@@ -314,6 +327,7 @@ infisical agent --config example-agent-config-file.yaml
**Description**: This function can be used to render the full list of secrets within a given project, environment and secret path. **Description**: This function can be used to render the full list of secrets within a given project, environment and secret path.
**Returns**: A single secret object with the following keys `Key, WorkspaceId, Value, Type, ID, and Comment` **Returns**: A single secret object with the following keys `Key, WorkspaceId, Value, Type, ID, and Comment`
</Accordion> </Accordion>
<Accordion title="getSecretByName"> <Accordion title="getSecretByName">