From b2ad30266a786614bd705b17d20275ce4dc2d4d2 Mon Sep 17 00:00:00 2001 From: Manuel Ganter Date: Tue, 11 Nov 2025 15:41:07 +0100 Subject: [PATCH] added username/password or token as env variable --- examples/ENV_VARS.md | 264 +++++++++++++++++++ examples/README.md | 55 +++- examples/authentication/README.md | 137 +++++++++- examples/authentication/env-vars-token.sh | 23 ++ examples/authentication/env-vars-userpass.sh | 24 ++ examples/authentication/env-vars.tf | 33 +++ internal/provider/provider.go | 50 +++- 7 files changed, 559 insertions(+), 27 deletions(-) create mode 100644 examples/ENV_VARS.md create mode 100755 examples/authentication/env-vars-token.sh create mode 100755 examples/authentication/env-vars-userpass.sh create mode 100644 examples/authentication/env-vars.tf diff --git a/examples/ENV_VARS.md b/examples/ENV_VARS.md new file mode 100644 index 0000000..4db4fc1 --- /dev/null +++ b/examples/ENV_VARS.md @@ -0,0 +1,264 @@ +# Environment Variables Reference + +This document provides a complete reference for all environment variables supported by the Edge Connect Terraform provider. + +## Supported Environment Variables + +| Variable | Type | Required | Description | +|----------|------|----------|-------------| +| `EDGE_CONNECT_ENDPOINT` | string | Yes | The Edge Connect API endpoint URL | +| `EDGE_CONNECT_TOKEN` | string | Conditional* | API token for authentication | +| `EDGE_CONNECT_USERNAME` | string | Conditional* | Username for authentication | +| `EDGE_CONNECT_PASSWORD` | string | Conditional* | Password for authentication | + +\* Either `EDGE_CONNECT_TOKEN` OR both `EDGE_CONNECT_USERNAME` and `EDGE_CONNECT_PASSWORD` must be provided. + +## Quick Start + +### Token Authentication + +```bash +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_TOKEN="your-api-token-here" + +terraform init +terraform plan +terraform apply +``` + +### Username/Password Authentication + +```bash +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_USERNAME="your-username" +export EDGE_CONNECT_PASSWORD="your-password" + +terraform init +terraform plan +terraform apply +``` + +## Configuration Precedence + +The provider reads configuration in the following order (highest to lowest precedence): + +1. **Explicit Configuration** - Values set directly in the provider block +2. **Environment Variables** - Values from environment variables +3. **Default Values** - Provider defaults (if any) + +### Example: Precedence in Action + +```hcl +provider "edge-connect" { + endpoint = "https://api.example.com" # This value is used + # token will be read from EDGE_CONNECT_TOKEN environment variable +} +``` + +If `EDGE_CONNECT_TOKEN` is set in the environment, it will be used for the token even though it's not specified in the configuration. + +## Usage Patterns + +### 1. Pure Environment Variable Configuration + +No explicit configuration needed in Terraform files: + +```hcl +provider "edge-connect" {} +``` + +All configuration comes from environment variables. + +### 2. Mixed Configuration + +Some values explicit, others from environment: + +```hcl +provider "edge-connect" { + endpoint = "https://api.edge-connect.example.com" + # token, username, and password from environment variables +} +``` + +### 3. Override Environment Variables + +Explicit configuration overrides environment variables: + +```hcl +provider "edge-connect" { + endpoint = "https://api.edge-connect.example.com" + token = var.edge_connect_token # Overrides EDGE_CONNECT_TOKEN +} +``` + +## Shell Integration + +### Bash/Zsh Profile + +Add to `~/.bashrc` or `~/.zshrc`: + +```bash +# Edge Connect API Configuration +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_TOKEN="your-token" +``` + +### direnv (Recommended) + +Create a `.envrc` file in your project directory: + +```bash +# .envrc +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_TOKEN="your-token" +``` + +Enable direnv: +```bash +direnv allow +``` + +Now environment variables are automatically loaded when you enter the directory. + +### CI/CD Systems + +#### GitHub Actions + +```yaml +- name: Terraform Apply + env: + EDGE_CONNECT_ENDPOINT: ${{ secrets.EDGE_CONNECT_ENDPOINT }} + EDGE_CONNECT_TOKEN: ${{ secrets.EDGE_CONNECT_TOKEN }} + run: | + terraform init + terraform apply -auto-approve +``` + +#### GitLab CI + +```yaml +terraform: + script: + - terraform init + - terraform apply -auto-approve + variables: + EDGE_CONNECT_ENDPOINT: $EDGE_CONNECT_ENDPOINT + EDGE_CONNECT_TOKEN: $EDGE_CONNECT_TOKEN +``` + +#### Jenkins + +```groovy +withEnv([ + "EDGE_CONNECT_ENDPOINT=https://api.edge-connect.example.com", + "EDGE_CONNECT_TOKEN=${env.EDGE_CONNECT_TOKEN}" +]) { + sh 'terraform init' + sh 'terraform apply -auto-approve' +} +``` + +## Secret Management Integration + +### AWS Secrets Manager + +```bash +export EDGE_CONNECT_TOKEN=$(aws secretsmanager get-secret-value \ + --secret-id edge-connect/token \ + --query SecretString \ + --output text) +``` + +### HashiCorp Vault + +```bash +export EDGE_CONNECT_TOKEN=$(vault kv get -field=token secret/edge-connect) +``` + +### Azure Key Vault + +```bash +export EDGE_CONNECT_TOKEN=$(az keyvault secret show \ + --name edge-connect-token \ + --vault-name my-vault \ + --query value -o tsv) +``` + +### Google Secret Manager + +```bash +export EDGE_CONNECT_TOKEN=$(gcloud secrets versions access latest \ + --secret="edge-connect-token") +``` + +## Security Best Practices + +1. **Never commit credentials to version control** + - Use `.gitignore` for files containing secrets + - Use environment variables or secret management systems + +2. **Use appropriate permissions** + - Restrict access to environment files + - Use IAM roles and policies in cloud environments + +3. **Rotate credentials regularly** + - Update environment variables when rotating tokens + - Use automated rotation with secret management systems + +4. **Use token authentication in production** + - More secure than username/password + - Easier to rotate and scope + +5. **Audit credential usage** + - Log when credentials are accessed + - Monitor for unauthorized usage + +## Troubleshooting + +### Check if environment variables are set: + +```bash +env | grep EDGE_CONNECT +``` + +### Verify values (mask sensitive data): + +```bash +echo "Endpoint: $EDGE_CONNECT_ENDPOINT" +echo "Token: ${EDGE_CONNECT_TOKEN:0:5}..." # Show only first 5 chars +``` + +### Clear environment variables: + +```bash +unset EDGE_CONNECT_ENDPOINT +unset EDGE_CONNECT_TOKEN +unset EDGE_CONNECT_USERNAME +unset EDGE_CONNECT_PASSWORD +``` + +### Common Issues + +**Problem:** Provider can't find credentials + +**Solution:** Verify environment variables are set in the current shell: +```bash +env | grep EDGE_CONNECT +``` + +**Problem:** Wrong credentials being used + +**Solution:** Check for explicit configuration overriding environment variables, or verify the correct environment variables are set. + +## Examples + +See the [authentication/](authentication/) directory for complete examples: + +- `env-vars.tf` - Pure environment variable configuration +- `env-vars-token.sh` - Shell script for token authentication +- `env-vars-userpass.sh` - Shell script for username/password authentication + +## Additional Resources + +- [Authentication Examples](authentication/README.md) - Detailed authentication documentation +- [Provider Configuration](README.md) - Main examples README diff --git a/examples/README.md b/examples/README.md index 44f093f..aa272a8 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,6 +2,14 @@ This directory contains example Terraform configurations demonstrating the usage of the Edge Connect Terraform provider. +## Quick Links + +- **[Environment Variables Reference](ENV_VARS.md)** - Complete guide to environment variable configuration +- **[Authentication Guide](authentication/README.md)** - Detailed authentication methods and best practices +- **[Basic Example](basic/)** - Simple getting started example +- **[Complete Example](complete/)** - Comprehensive multi-resource example +- **[Data Sources Example](data-sources/)** - Using data sources to query existing resources + ## Available Examples ### Authentication Examples (`authentication/`) @@ -101,13 +109,34 @@ provider "edge-connect" { ### Configuration Options -- `endpoint` (required): The Edge Connect API endpoint URL -- `token` (optional, sensitive): Authentication token for the Edge Connect API. Required if username/password are not provided. -- `username` (optional): Username for the Edge Connect API. Required if token is not provided. -- `password` (optional, sensitive): Password for the Edge Connect API. Required if token is not provided. +- `endpoint` (optional): The Edge Connect API endpoint URL. Can also be set via `EDGE_CONNECT_ENDPOINT` environment variable. +- `token` (optional, sensitive): Authentication token for the Edge Connect API. Required if username/password are not provided. Can also be set via `EDGE_CONNECT_TOKEN` environment variable. +- `username` (optional): Username for the Edge Connect API. Required if token is not provided. Can also be set via `EDGE_CONNECT_USERNAME` environment variable. +- `password` (optional, sensitive): Password for the Edge Connect API. Required if token is not provided. Can also be set via `EDGE_CONNECT_PASSWORD` environment variable. **Important:** You must use either token authentication OR username/password authentication, but not both. +### Environment Variables + +All provider configuration can be set via environment variables: + +| Environment Variable | Description | +|---------------------|-------------| +| `EDGE_CONNECT_ENDPOINT` | API endpoint URL | +| `EDGE_CONNECT_TOKEN` | API token (for token auth) | +| `EDGE_CONNECT_USERNAME` | Username (for username/password auth) | +| `EDGE_CONNECT_PASSWORD` | Password (for username/password auth) | + +**Example using environment variables:** +```bash +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_TOKEN="your-token" +terraform init +terraform apply +``` + +See [authentication/README.md](authentication/README.md) for detailed information about environment variable usage. + ## Resources ### edge-connect_app @@ -195,6 +224,8 @@ Retrieves information about an existing application instance. ## Getting Started +### Option 1: Using Configuration Files + 1. Choose an example that fits your use case 2. Navigate to the example directory 3. Copy `terraform.tfvars.example` to `terraform.tfvars` @@ -203,6 +234,19 @@ Retrieves information about an existing application instance. 6. Run `terraform plan` to see what will be created 7. Run `terraform apply` to create the resources +### Option 2: Using Environment Variables (Recommended) + +1. Choose an example that fits your use case +2. Navigate to the example directory +3. Set environment variables: + ```bash + export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" + export EDGE_CONNECT_TOKEN="your-token" + ``` +4. Run `terraform init` to initialize the provider +5. Run `terraform plan` to see what will be created +6. Run `terraform apply` to create the resources + ## Cleanup To destroy the resources created by these examples: @@ -217,6 +261,9 @@ terraform destroy - The `terraform.tfvars` file is gitignored by default - Always review the plan output before applying changes - Some resources may take time to provision +- **Recommended:** Use environment variables for credentials in production and CI/CD environments +- Environment variables take precedence when both are provided +- Consider using tools like `direnv` for automatic environment variable management per directory ## Support diff --git a/examples/authentication/README.md b/examples/authentication/README.md index dbeb5b3..1592c5d 100644 --- a/examples/authentication/README.md +++ b/examples/authentication/README.md @@ -2,6 +2,13 @@ This directory contains examples demonstrating the different authentication methods supported by the Edge Connect Terraform provider. +## Configuration Methods + +The provider supports configuration via: +1. **Explicit Configuration** - Setting values directly in your Terraform files +2. **Environment Variables** - Using environment variables (recommended for CI/CD and production) +3. **Hybrid Approach** - Mixing both methods (explicit config takes precedence) + ## Authentication Methods The provider supports two mutually exclusive authentication methods: @@ -25,8 +32,15 @@ provider "edge-connect" { } ``` -**Environment Variable:** -You can also set credentials via environment variables: +**Environment Variables:** +You can set credentials directly via provider-specific environment variables: +```bash +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_TOKEN="your-token-here" +terraform apply +``` + +Alternatively, use Terraform variables: ```bash export TF_VAR_edge_connect_token="your-token-here" terraform apply @@ -53,13 +67,92 @@ provider "edge-connect" { ``` **Environment Variables:** -You can also set credentials via environment variables: +You can set credentials directly via provider-specific environment variables: +```bash +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_USERNAME="your-username" +export EDGE_CONNECT_PASSWORD="your-password" +terraform apply +``` + +Alternatively, use Terraform variables: ```bash export TF_VAR_edge_connect_username="your-username" export TF_VAR_edge_connect_password="your-password" terraform apply ``` +## Environment Variables + +The provider supports the following environment variables that can be used instead of explicit configuration: + +| Environment Variable | Description | Required | +|---------------------|-------------|----------| +| `EDGE_CONNECT_ENDPOINT` | API endpoint URL | Yes | +| `EDGE_CONNECT_TOKEN` | API token | Conditional* | +| `EDGE_CONNECT_USERNAME` | Username for authentication | Conditional* | +| `EDGE_CONNECT_PASSWORD` | Password for authentication | Conditional* | + +\* Either `EDGE_CONNECT_TOKEN` OR both `EDGE_CONNECT_USERNAME` and `EDGE_CONNECT_PASSWORD` must be provided. + +### Using Environment Variables Only + +**File:** `env-vars.tf` + +You can configure the provider without any explicit configuration by using environment variables: + +```hcl +provider "edge-connect" { + # Configuration will be read from environment variables +} +``` + +**Token Authentication:** +```bash +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_TOKEN="your-token-here" +terraform init +terraform plan +terraform apply +``` + +**Username/Password Authentication:** +```bash +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_USERNAME="your-username" +export EDGE_CONNECT_PASSWORD="your-password" +terraform init +terraform plan +terraform apply +``` + +### Precedence Rules + +When both explicit configuration and environment variables are provided: +1. Explicit configuration values take precedence +2. If a value is not explicitly configured, the provider checks environment variables +3. If neither is provided, validation errors occur + +**Example of precedence:** +```hcl +provider "edge-connect" { + endpoint = "https://api.edge-connect.example.com" # Explicit + # token will be read from EDGE_CONNECT_TOKEN env var +} +``` + +### Helper Scripts + +See the example shell scripts in this directory: +- `env-vars-token.sh` - Set up token authentication via environment variables +- `env-vars-userpass.sh` - Set up username/password authentication via environment variables + +Make them executable and source them: +```bash +chmod +x env-vars-token.sh +source ./env-vars-token.sh +``` + ## Important Notes 1. **Mutual Exclusivity:** You must use EITHER token OR username/password, not both. The provider will return an error if both methods are provided. @@ -70,9 +163,11 @@ terraform apply 3. **Security Best Practices:** - Never commit credentials to version control + - Prefer environment variables over hardcoded values in Terraform files - Use environment variables or secure secret management systems - Mark sensitive variables with `sensitive = true` - Use `.gitignore` to exclude `terraform.tfvars` files + - Consider using tools like `direnv` for automatic environment variable management ## Validation Rules @@ -89,8 +184,8 @@ The provider validates authentication credentials with the following rules: Error: Missing Authentication Credentials The provider requires authentication credentials. Please provide either: - - token: API token for authentication, or - - username and password: Username and password for authentication + - token: API token for authentication (via 'token' attribute or EDGE_CONNECT_TOKEN environment variable), or + - username and password: Username and password for authentication (via 'username'/'password' attributes or EDGE_CONNECT_USERNAME/EDGE_CONNECT_PASSWORD environment variables) ``` ### Conflicting Methods @@ -110,6 +205,8 @@ Both username and password must be provided together for username/password authe ## Testing Examples +### Using Explicit Configuration + To test token authentication: ```bash cd examples/authentication @@ -127,9 +224,31 @@ terraform plan \ -target=edge-connect_app.userpass_example ``` +### Using Environment Variables + +To test with environment variables (token auth): +```bash +cd examples/authentication +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_TOKEN="your-token" +terraform init +terraform plan -target=edge-connect_app.env_example +``` + +To test with environment variables (username/password auth): +```bash +cd examples/authentication +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" +export EDGE_CONNECT_USERNAME="your-username" +export EDGE_CONNECT_PASSWORD="your-password" +terraform init +terraform plan -target=edge-connect_app.env_example +``` + ## Recommendations -- **Production Environments:** Use token-based authentication with properly scoped and rotated tokens -- **Development Environments:** Either method is acceptable, but token auth is still recommended -- **CI/CD Pipelines:** Use token-based authentication with secrets management (e.g., HashiCorp Vault, AWS Secrets Manager) -- **Local Development:** Consider using environment variables or `.tfvars` files (excluded from git) for credentials +- **Production Environments:** Use token-based authentication with properly scoped and rotated tokens via environment variables +- **Development Environments:** Either method is acceptable, but token auth is still recommended. Use environment variables or `.tfvars` files +- **CI/CD Pipelines:** Use token-based authentication with secrets management (e.g., HashiCorp Vault, AWS Secrets Manager) passed as environment variables +- **Local Development:** Use environment variables with tools like `direnv` for automatic management +- **Configuration Management:** Prefer environment variables over hardcoded values for better security and flexibility diff --git a/examples/authentication/env-vars-token.sh b/examples/authentication/env-vars-token.sh new file mode 100755 index 0000000..6a0f40f --- /dev/null +++ b/examples/authentication/env-vars-token.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Example: Using environment variables for token authentication +# +# This script demonstrates how to set environment variables for +# token-based authentication with the Edge Connect provider. + +# Set the API endpoint +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" + +# Set the API token +export EDGE_CONNECT_TOKEN="your-api-token-here" + +# Now you can run Terraform commands without passing credentials +echo "Environment variables set. You can now run:" +echo " terraform init" +echo " terraform plan" +echo " terraform apply" + +# Example: Run terraform plan +# terraform plan + +# Note: You can also set these in your shell profile (~/.bashrc, ~/.zshrc) +# or use a tool like direnv for directory-specific environment variables diff --git a/examples/authentication/env-vars-userpass.sh b/examples/authentication/env-vars-userpass.sh new file mode 100755 index 0000000..7fd2a85 --- /dev/null +++ b/examples/authentication/env-vars-userpass.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Example: Using environment variables for username/password authentication +# +# This script demonstrates how to set environment variables for +# username/password authentication with the Edge Connect provider. + +# Set the API endpoint +export EDGE_CONNECT_ENDPOINT="https://api.edge-connect.example.com" + +# Set username and password +export EDGE_CONNECT_USERNAME="your-username" +export EDGE_CONNECT_PASSWORD="your-password" + +# Now you can run Terraform commands without passing credentials +echo "Environment variables set. You can now run:" +echo " terraform init" +echo " terraform plan" +echo " terraform apply" + +# Example: Run terraform plan +# terraform plan + +# Note: You can also set these in your shell profile (~/.bashrc, ~/.zshrc) +# or use a tool like direnv for directory-specific environment variables diff --git a/examples/authentication/env-vars.tf b/examples/authentication/env-vars.tf new file mode 100644 index 0000000..8d67a9e --- /dev/null +++ b/examples/authentication/env-vars.tf @@ -0,0 +1,33 @@ +# Example: Environment Variable Authentication +# +# This example demonstrates how to authenticate with the Edge Connect +# provider using environment variables instead of explicit configuration. + +terraform { + required_providers { + edge-connect = { + source = "local/edge-connect" + } + } +} + +# Provider configured entirely via environment variables +# No explicit configuration needed - provider will read from: +# - EDGE_CONNECT_ENDPOINT +# - EDGE_CONNECT_TOKEN (for token auth) +# OR +# - EDGE_CONNECT_USERNAME and EDGE_CONNECT_PASSWORD (for username/password auth) + +provider "edge-connect" { + # All values will be read from environment variables +} + +# Example resource +resource "edge-connect_app" "env_example" { + name = "env-var-app" + version = "1.0.0" +} + +output "app_id" { + value = edge-connect_app.env_example.id +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 6889e98..db60ef2 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -2,6 +2,7 @@ package provider import ( "context" + "os" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/path" @@ -34,25 +35,29 @@ func (p *EdgeConnectProvider) Metadata(ctx context.Context, req provider.Metadat func (p *EdgeConnectProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) { resp.Schema = schema.Schema{ - MarkdownDescription: "Provider for Edge Connect API. Supports authentication via token or username/password.", + MarkdownDescription: "Provider for Edge Connect API. Supports authentication via token or username/password. " + + "Configuration can be provided via attributes or environment variables.", Attributes: map[string]schema.Attribute{ "endpoint": schema.StringAttribute{ - MarkdownDescription: "Edge Connect API endpoint", - Required: true, + MarkdownDescription: "Edge Connect API endpoint. Can also be set via `EDGE_CONNECT_ENDPOINT` environment variable.", + Optional: true, }, "token": schema.StringAttribute{ - MarkdownDescription: "Edge Connect API token. Required if username/password are not provided.", - Optional: true, - Sensitive: true, + MarkdownDescription: "Edge Connect API token. Required if username/password are not provided. " + + "Can also be set via `EDGE_CONNECT_TOKEN` environment variable.", + Optional: true, + Sensitive: true, }, "username": schema.StringAttribute{ - MarkdownDescription: "Edge Connect API username. Required if token is not provided.", - Optional: true, + MarkdownDescription: "Edge Connect API username. Required if token is not provided. " + + "Can also be set via `EDGE_CONNECT_USERNAME` environment variable.", + Optional: true, }, "password": schema.StringAttribute{ - MarkdownDescription: "Edge Connect API password. Required if token is not provided.", - Optional: true, - Sensitive: true, + MarkdownDescription: "Edge Connect API password. Required if token is not provided. " + + "Can also be set via `EDGE_CONNECT_PASSWORD` environment variable.", + Optional: true, + Sensitive: true, }, }, } @@ -67,17 +72,34 @@ func (p *EdgeConnectProvider) Configure(ctx context.Context, req provider.Config return } + // Read configuration values, falling back to environment variables endpoint := data.Endpoint.ValueString() + if endpoint == "" { + endpoint = os.Getenv("EDGE_CONNECT_ENDPOINT") + } + token := data.Token.ValueString() + if token == "" { + token = os.Getenv("EDGE_CONNECT_TOKEN") + } + username := data.Username.ValueString() + if username == "" { + username = os.Getenv("EDGE_CONNECT_USERNAME") + } + password := data.Password.ValueString() + if password == "" { + password = os.Getenv("EDGE_CONNECT_PASSWORD") + } // Validate endpoint if endpoint == "" { resp.Diagnostics.AddAttributeError( path.Root("endpoint"), "Missing Edge Connect API Endpoint", - "The provider cannot create the Edge Connect API client as there is a missing or empty value for the Edge Connect API endpoint.", + "The provider cannot create the Edge Connect API client as there is a missing or empty value for the Edge Connect API endpoint. "+ + "Set the endpoint value in the configuration or use the EDGE_CONNECT_ENDPOINT environment variable.", ) } @@ -89,8 +111,8 @@ func (p *EdgeConnectProvider) Configure(ctx context.Context, req provider.Config resp.Diagnostics.AddError( "Missing Authentication Credentials", "The provider requires authentication credentials. Please provide either:\n"+ - " - token: API token for authentication, or\n"+ - " - username and password: Username and password for authentication", + " - token: API token for authentication (via 'token' attribute or EDGE_CONNECT_TOKEN environment variable), or\n"+ + " - username and password: Username and password for authentication (via 'username'/'password' attributes or EDGE_CONNECT_USERNAME/EDGE_CONNECT_PASSWORD environment variables)", ) }