Skip to content

Parameters

Parameters retrieves configuration from SSM, Secrets Manager, DynamoDB, AppConfig Data and AppConfig Agent. Shared caching and JSON/Base64 transforms live in github.com/rambow-cloud/powertools-lambda-go/parameters; service adapters are subpackages of that module.

See installation and the compatibility baseline.

Complete example

This complete offline example demonstrates the shared cache with an application retrieval callback. It makes no AWS request. Save it in an empty directory inside the checkout and run go run main.go with CGO_ENABLED=0. For an actual SSM client, use SSM usage below; create the provider once before serving Lambda invocations.

package main

import (
    "context"
    "encoding/json"
    "fmt"
    stdlog "log"
    "time"

    "github.com/rambow-cloud/powertools-lambda-go/parameters"
)

func main() {
    cache := parameters.NewCache(time.Now)
    fetches := 0
    fetch := func(context.Context) (any, error) {
        fetches++
        return `{"enabled":true,"limit":3}`, nil
    }
    options := parameters.Options{
        Transform: parameters.JSON,
        MaxAge:    parameters.Age(30 * time.Second),
    }
    for range 2 {
        value, err := cache.Get(context.Background(), "/orders/config", options, fetch)
        if err != nil {
            stdlog.Fatal(err)
        }
        encoded, err := json.Marshal(value)
        if err != nil {
            stdlog.Fatal(err)
        }
        fmt.Println(string(encoded))
    }
    fmt.Printf("fetches=%d\n", fetches)
}

Input and output

Stdout is exactly the following. Both calls return the decoded object, but the callback runs only once because the second call uses the still-valid cache entry. Setting options.ForceFetch = true before the second call would invoke it again. cache.ClearCache() removes cached values; it does not change the underlying configuration service. With an AWS provider, SDK errors are returned to your handler rather than logged as successful values.

{"enabled":true,"limit":3}
{"enabled":true,"limit":3}
fetches=1

Objects and lifecycle

Object Responsibility
cache / explicit provider Keep one instance across warm invocations to retain cached values; no background polling.
options Per-call transform, TTL, force-fetch and missing/error policy.
value any: JSON objects are map[string]any, arrays are []any, numbers are float64; inspect or decode explicitly.
ctx Caller cancellation/deadline reaches retrieval and SDK operations.

TypeScript feature coverage

Compared with the official v2.35.0 parameters guide and the pinned npm implementation. The table maps capabilities; it does not certify every native type or service behavior.

TypeScript feature Go API or approach Compatibility scope
SSM read / path / named batch / write ssm.New, provider methods and convenience helpers Pagination, decryption and reference batch quirks documented below.
Secrets / DynamoDB Explicit providers or Secrets helper SDK v2 clients; DynamoDB decoding preserves large integers.
AppConfig / Agent Data provider or Agent GetConfig Data sessions retain tokens; Agent has no additional cache.
TTL / fresh values / clearing MaxAge, ForceFetch, ClearCache, ClearCaches Five-second ordinary default; duration/native edges differ.
Transforms / missing values JSON, Binary, Auto, ThrowOnMissing Explicit Go results/errors; snapshots isolate cached objects.
Custom provider / SDK arguments Cache.Get, injected service interfaces and inputs Callbacks replace inheritance; callers supply region/credentials/permissions.

Executable evidence: parameters/parameters_test.go, parameters/providers_test.go. See the verification scope and project progress for open gates.

API map

TypeScript API Go API
SSMProvider parameters/ssm.New(client)
getParameter, getParameters, getParametersByName, setParameter ssm.GetParameter, ssm.GetParameters, ssm.GetParametersByName, ssm.SetParameter
SecretsProvider, getSecret parameters/secrets.New(client), secrets.GetSecret
DynamoDBProvider parameters/dynamodb.New(client, Config)
AppConfigProvider, getAppConfig parameters/appconfig.New(client, Config), appconfig.GetAppConfig
AppConfig Agent getConfig parameters/appconfigagent.GetConfig
Custom BaseProvider parameters.Cache.Get / GetMultiple with retrieval callbacks
clearCaches parameters.ClearCaches() for default providers
Provider clearCache provider.ClearCache() for explicit providers

All retrievals accept context.Context. Providers accept AWS SDK for Go v2 clients through service interfaces, allowing custom credentials, region, endpoints, transports, and tracing. Native SDK input structs carry per-call options; adapters copy them before overriding parameter names, table keys, and other provider-owned fields.

Convenience functions load standard AWS configuration lazily on first use. Initialization failure can be retried; concurrent initialization happens once, with cancellable waiters. Each default provider retains its initial configuration. Default AppConfig retains the application/environment from its first successful initialization, matching the reference. Use explicit providers for different regions, accounts, applications, or environments.

SSM usage

import (
    "context"
    "time"

    "github.com/aws/aws-sdk-go-v2/aws"
    sdk "github.com/aws/aws-sdk-go-v2/service/ssm"
    "github.com/rambow-cloud/powertools-lambda-go/parameters"
    "github.com/rambow-cloud/powertools-lambda-go/parameters/ssm"
)

// Create this closure once before lambda.Start to retain the provider cache.
func configurationReader(cfg aws.Config) func(context.Context) (any, error) {
    provider := ssm.New(sdk.NewFromConfig(cfg))
    return func(ctx context.Context) (any, error) {
        return provider.Get(ctx, "/orders/config", ssm.GetOptions{
            Options: parameters.Options{
                Transform: parameters.JSON,
                MaxAge: parameters.Age(30 * time.Second),
                ThrowOnMissing: true,
            },
            Decrypt: aws.Bool(true),
        })
    }
}

For standard Lambda AWS configuration, use the convenience function:

value, err := ssm.GetParameter(ctx, "/orders/config", ssm.GetOptions{
    Options: parameters.Options{Transform: parameters.JSON},
})

GetMultiple(ctx, path, MultipleOptions) follows all SSM pages and returns names relative to the requested path. Recursive defaults to SDK behavior. Decrypt overrides SDK WithDecryption, which overrides POWERTOOLS_PARAMETERS_SSM_DECRYPT. Shared extended boolean parsing accepts 1/y/yes/t/true/on and 0/n/no/f/false/off, ignoring case and surrounding whitespace; invalid values return errors.

Set(ctx, name, value, *sdk.PutParameterInput) returns the version. Defaults are Type=String, Tier=Standard, and Overwrite=false. Native options cover KMS key, description, policies, tags, tier, and overwrite. Explicit name/value arguments take precedence. Writes preserve cached reads, matching the reference; use ForceFetch or ClearCache to observe a write immediately.

Named batches

values, err := provider.GetParametersByName(ctx, map[string]ssm.GetOptions{
    "/orders/config": {Options: parameters.Options{Transform: parameters.JSON}},
    "/orders/feature": {},
}, ssm.ByNameOptions{ThrowOnError: aws.Bool(false)})

Per-name max age, transform, and decryption override batch defaults. Pending names are fetched in batches of at most ten. All-encrypted batches use GetParameters with decryption. Mixed batches use individual GetParameter calls for encrypted names and batches for the remainder. Graceful mode returns failed names as values["_errors"].([]string); _errors is reserved in this mode. SDK transport/service failures from a batch still return errors. Graceful transform failures produce nil entries without adding names to _errors.

The pinned implementation has observable inconsistencies that are deliberately retained:

  • Encrypted names in mixed batches bypass transforms and cache, returning raw values on every call.
  • Batched retrieval ignores ForceFetch. Clear the cache or use individual Get with ForceFetch to refresh.
  • Batch max age defaults to five seconds independently of the environment. Explicit zero also falls back to five seconds when storing a truthy result.
  • Empty batch strings become nil. Transformed false, zero, and null values are returned but not cached by this path.

Reference fixtures cover mixed decryption, repeat requests, empty values, graceful missing names, outputs, and SDK operation sequences. Go leaves input maps unmodified and sorts names for deterministic batching.

Cache and transformations

parameters.Options has MaxAge *time.Duration, ForceFetch, Transform, ThrowOnMissing, and ThrowOnTransformError. Use parameters.Age(0) for explicit zero; nil selects the default. Ordinary retrievals read POWERTOOLS_PARAMETERS_MAX_AGE per call, defaulting to five seconds only when absent. Invalid numeric input returns a shared typed configuration error before cache lookup. The legacy public Lifetime() accessor retains its fallback-on-error behavior. Non-positive lifetimes skip new entries but do not bypass existing valid entries; that requires ForceFetch.

Expiry is checked on access; a value remains valid at the exact expiry boundary. Retrieval/transform errors, missing raw values, and empty collections are not cached. Cache keys include name, transform, and single/multiple operation. They exclude SDK options, decryption, version selectors, and strict-error flags. Use separate providers or forced retrieval when changing those settings. Lifetime is fixed on insertion. A strict transform call can reuse a cached permissive result unless forced.

The cache protects maps with a mutex and copies supported mutable decoded values on storage/retrieval. Network calls run outside the lock; concurrent misses may fetch independently. ClearCache prevents in-flight Get/GetMultiple callbacks from repopulating cleared entries. Batched Lookup/Store operations are individually synchronized but are not an atomic transaction with clearing; join batches before clearing when strict invalidation is required. There is no background refresh or capacity eviction. Each Lambda execution environment has its own cache.

Transform Result
Unset Original string, bytes, or decoded DynamoDB value
parameters.JSON JSON objects as map[string]any, arrays as []any, numbers as float64
parameters.Binary Base64-decoded UTF-8 string after Commons standard-alphabet and padding validation
parameters.Auto JSON for .json, base64 for .binary, otherwise unchanged; suffixes ignore case

Transform names ignore case. Single-value failures return *parameters.TransformParameterError. Multiple retrievals retain failed entries as nil by default; ThrowOnTransformError returns the error. Non-string/non-byte values pass through. JSON null and missing values both map to nil; successfully decoded JSON null can still be cached by ordinary Get.

ThrowOnMissing returns *parameters.ParameterNotFoundError for absent raw values. SSM/Secrets Manager normalize SDK not-found exceptions only with this option enabled; otherwise those exceptions remain available under *parameters.GetParameterError. Use errors.As for types and errors.Is for cancellation/deadlines. Writes return *parameters.SetParameterError on failure.

Other providers

Secrets Manager uses GetSecretValue. Nonempty SecretString takes precedence, followed by raw SecretBinary bytes. The SDK already decodes wire-level base64 for SecretBinary; leaving the transform unset preserves those bytes. Selecting Binary requests an additional decoding step, matching the reference. SDK options accept version ID/stage. Empty strings without binary values count as missing. Bulk retrieval is not supported by the reference provider and is not exposed in Go.

DynamoDB requires TableName; attributes default to id, sk, and value. Get sends a partition-key lookup and value projection. GetMultiple queries that partition, follows every page, and indexes values by sort attribute. The SDK decodes native maps, lists, sets, booleans, numbers, nulls, and binary. SDK options support consistent reads, limits, index selection, and compatible fields. Provider-owned key/projection fields take precedence. Composite-key single-item lookups need custom retrieval callbacks; the reference also supplies only its partition key for Get.

AppConfig Data requires application/environment; application falls back to POWERTOOLS_SERVICE_NAME. Session SDK options accept RequiredMinimumPollIntervalInSeconds. Tokens and last known bytes are retained per profile. Tokens rotate after polling and expire locally after 23 hours 45 minutes. Same-profile requests are serialized because tokens are single-use; waiters can cancel. Empty updates return the previous bytes. Clearing the transformed cache keeps session/last-value state. Failed polls discard possibly consumed tokens so the next call starts a new session.

Like the pinned reference, AppConfig uses the caller's cache lifetime rather than scheduling from NextPollIntervalInSeconds. Set lifetime to the service's permitted polling interval in production. ForceFetch bypasses the cache; no background poller is created.

AppConfig Agent performs one HTTP GET per call with no extra cache. Options include application, environment, transform, timeout, and missing behavior. Timeout defaults to three seconds; AWS_APPCONFIG_EXTENSION_HTTP_PORT defaults to 2772. URL identifiers are escaped individually. Application falls back to the service name. HTTP 404 means missing; other non-success statuses return retrieval errors.

Agent Lambda detection follows the reference: AWS_LAMBDA_INITIALIZATION_TYPE is set and not unknown, with development mode disabled. Outside Lambda it reads POWERTOOLS_APPCONFIG_AGENT_RETURN_VALUE; empty means missing. Endpoint explicitly enables HTTP to a local agent outside Lambda. HTTPClient accepts an instrumented transport. Error messages omit response bodies to avoid copying configuration data into diagnostics.

Compatibility boundaries

All five providers and the reference convenience-function families are implemented. Complete JavaScript parity is not claimed:

  • Go uses contexts, SDK v2 inputs, typed errors, duration pointers, and nil instead of JavaScript-specific values/exceptions.
  • Cache results are isolated snapshots; single/multiple entries cannot collide. The reference returns shared objects and uses the same string-key format for both operations.
  • Unknown transform names return errors. Base64 validation now uses the shared Commons contract; prior permissive handling was removed. Extreme duration values and fractional TTL boundaries still differ from JavaScript date handling.
  • DynamoDB now uses the shared number-preserving SDK decoder: safe values become float64, large integer strings become *big.Int, and unsupported large decimal/exponent forms fail. Set identity, native type representation, and malformed item cases still need exhaustive parity coverage.
  • AppConfig serializes session access, restarts sessions after failed polls, and rejects empty application/environment configuration earlier.
  • SDK-specific error messages, prototype-only base-provider methods, and exhaustive invalid-configuration diagnostics are not reproduced. The shared SDK middleware now adds one feature marker using the Go version, without global environment mutation.

Validation

On 2026-09-14, the complete Go test suite, vet, and both Linux architecture builds passed with CGO disabled. Local Docker Lambda acceptance passed 94/94 assertions across five invocations. All five providers ran with Logger, Metrics, and OTel Tracer. Checks include warm cache reuse, forced refresh, AppConfig token rotation/empty updates, and agent-owned caching. Containers and the internal network were removed.

Commons migration validation on the same date passed the complete regression suite and 100/100 Docker assertions, including Metadata and shared SDK marker composition. Existing Parameters cases remain in the suite. COMMONS_REUSE.md records the migrations and retained provider-specific policies.

Unit tests execute real SDK requests against loopback fixtures and cover reference output, cache/transforms, writes/batches, pagination, default helpers/global clearing, and functional concurrency. Fixtures do not establish IAM, KMS, service quotas, throttling, or live AppConfig delivery. No AWS resources were deployed for this module. Remaining parity, cloud, and performance gates stay unchecked in CHECKLIST.md. See LOCAL_VALIDATION.md for runtime evidence.