Python & TypeScript · read-only secrets

Python & TypeScript · segredos somente leitura

One contract.
Any secret store.

Um contrato.
Qualquer cofre de segredos.

Your code asks for database/password. Whether that lives in AWS Secrets Manager, GCP Parameter Manager or a dictionary in a test does not change the call — only which distribution you install.

Seu código pede database/password. Se isso mora no AWS Secrets Manager, no GCP Parameter Manager ou num dicionário de teste, a chamada não muda — muda apenas qual distribuição você instala.

How a name is built
Como um nome é montado
envprod
projectbilling
prefixnot setvazio
namedatabase/password
resolves to resolve para /prod/billing/database/password
pythontypescript
from secret_kernel.factory import (
    CreateSecretClientConfig,
    create_secret_client,
)
from secret_kernel.provider_aws_parameter_store import (
    AwsParameterStoreProviderOptions,
)

client = create_secret_client(
    CreateSecretClientConfig(
        provider="aws-parameter-store",
        env="prod",
        project="billing",
        options=AwsParameterStoreProviderOptions(
            region="us-east-1",
        ),
    )
)

secret = await client.get_secret("database/password")
# secret.value — reads /prod/billing/database/password
import {
  SecretProvider,
  createSecretClient,
} from '@secret-kernel/factory';

const client = await createSecretClient({
  provider: SecretProvider.AwsParameterStore,
  env: 'prod',
  project: 'billing',
  options: { region: 'us-east-1' },
});

const secret = await client.getSecret('database/password');
// secret.value — reads /prod/billing/database/password
01

What it refuses to do

O que ele se recusa a fazer

The scope is the feature. A narrow contract is one you can reason about.

O escopo é a feature. Um contrato estreito é um contrato sobre o qual você consegue raciocinar.

  • Read-only. No write, no delete, no rotation, no batch read, no explicit historical version.
  • Latest version only. When a provider supports versions, the kernel always reads the current one.
  • Cross-environment reads are opt-in, one call at a time. The client's env applies unless a call says otherwise. Replacing it is never implicit and never a default, and omit_envomitEnv still wins over it — a service reading another environment is usually a defect, but the caller sometimes knows better than the process context.
  • Provider options never leak. region belongs to AWS, project_idprojectId to GCP. The shared contract knows neither.
  • Failures are never cached. A missing secret that appears later is found on the next read.
  • Somente leitura. Sem escrita, remoção, rotação, leitura em lote ou versão histórica explícita.
  • Apenas a última versão. Quando o provider suporta versões, o kernel sempre lê a atual.
  • Leitura entre ambientes é opt-in, uma chamada por vez. O env do client vale a menos que uma chamada diga o contrário. Substituí-lo nunca é implícito nem default, e omit_envomitEnv continua vencendo — um serviço lendo outro ambiente é normalmente um defeito, mas quem chama às vezes sabe mais que o contexto do processo.
  • Opções de provider não vazam. region é da AWS, project_idprojectId é do GCP. O contrato compartilhado não conhece nenhuma das duas.
  • Falhas nunca são cacheadas. Um segredo ausente que aparece depois é encontrado na leitura seguinte.

Writing, rotating and versioning stay outside this contract by design.

Escrita, rotação e versionamento ficam fora deste contrato por decisão de projeto.

02

Install and first read

Instalação e primeira leitura

Nothing is bundled. Install the contract, the shared core, the factory and the one provider you need.

Nada vem embutido. Instale o contrato, o core compartilhado, a factory e o único provider de que você precisa.

Step 1 · install the base

Passo 1 · instale a base

The contract, the shared core and the factory. No provider yet — that is step 2, and it is a separate distribution so an AWS-only service never pulls a GCP SDK.

O contrato, o core compartilhado e a factory. Nenhum provider ainda — isso é o passo 2, e ele é uma distribuição separada, então um serviço só-AWS nunca baixa um SDK do GCP.

contracts depends on nothing. A consumer that only declares types or catches errors installs that one package alone.

contracts não depende de nada. Quem só declara tipos ou captura erros instala apenas esse pacote.

uvnpmshell
$ uv add secret-kernel-contracts secret-kernel-core \
    secret-kernel-factory
$ npm install @secret-kernel/contracts @secret-kernel/core \
    @secret-kernel/factory

Step 2 · add a provider and read

Passo 2 · adicione um provider e leia

Pick where the secret lives. The call is identical either way — only the provider alias and its typed options change, which is the whole point of the contract.

Escolha onde o segredo mora. A chamada é idêntica nos dois casos — mudam apenas o alias do provider e suas opções tipadas, que é justamente o propósito do contrato.

in-memory

For local development, CI and tests. Reads preloaded values or environment variables, so nothing needs a cloud account.

Para desenvolvimento local, CI e testes. Lê valores pré-carregados ou variáveis de ambiente, então nada precisa de conta em nuvem.

With env_secretsenvSecrets, the key is the resolved name without the leading slash, non-alphanumerics replaced by _, uppercased and prefixed: /dev/my-app/database becomes SECRET_KERNEL_DEV_MY_APP_DATABASE. Preloaded secrets win over the environment.

Com env_secretsenvSecrets, a chave é o nome resolvido sem a barra inicial, não-alfanuméricos trocados por _, em maiúsculas e com prefixo: /dev/my-app/database vira SECRET_KERNEL_DEV_MY_APP_DATABASE. Segredos pré-carregados vencem o ambiente.

uvnpmshell
$ uv add secret-kernel-provider-in-memory
$ npm install @secret-kernel/provider-in-memory
in-memoryin-memory
from secret_kernel.factory import (
    CreateSecretClientConfig,
    create_secret_client,
)
from secret_kernel.provider_in_memory import (
    InMemoryProviderOptions,
)

client = create_secret_client(
    CreateSecretClientConfig(
        provider="in-memory",
        env="dev",
        project="my-app",
        options=InMemoryProviderOptions(
            secrets={"/dev/my-app/database/password": "s3cr3t"},
            env_secrets=True,
        ),
    )
)

secret = await client.get_secret("database/password")
# secret.value == "s3cr3t"
import {
  SecretProvider,
  createSecretClient,
} from '@secret-kernel/factory';

const client = await createSecretClient({
  provider: SecretProvider.InMemory,
  env: 'dev',
  project: 'my-app',
  options: {
    secrets: { '/dev/my-app/database/password': 's3cr3t' },
    envSecrets: true,
  },
});

const secret = await client.getSecret('database/password');
// secret.value === 's3cr3t'
aws-parameter-store

For a real store. Reads SecureString parameters, the low-cost option in AWS.

Para um cofre de verdade. Lê parâmetros SecureString, a opção de baixo custo na AWS.

Pass credentials to be explicit, or leave it out and the AWS SDK's own chain applies. Explicit credentials take precedence.

Passe credentials para ser explícito, ou omita e a própria cadeia do SDK da AWS se aplica. Credenciais explícitas têm precedência.

Only the provider and its options differ from the block above. get_secretgetSecret is the same call.

Só o provider e suas opções diferem do bloco acima. get_secretgetSecret é a mesma chamada.

uvnpmshell
$ uv add secret-kernel-provider-aws-parameter-store
$ npm install @secret-kernel/provider-aws-parameter-store
aws-parameter-storeaws-parameter-store
from secret_kernel.provider_aws_parameter_store import (
    AwsParameterStoreProviderOptions,
)

client = create_secret_client(
    CreateSecretClientConfig(
        provider="aws-parameter-store",
        env="prod",
        project="billing",
        options=AwsParameterStoreProviderOptions(
            region="us-east-1",
        ),
    )
)

secret = await client.get_secret("database/password")
# reads /prod/billing/database/password
const client = await createSecretClient({
  provider: SecretProvider.AwsParameterStore,
  env: 'prod',
  project: 'billing',
  options: { region: 'us-east-1' },
});

const secret = await client.getSecret('database/password');
// reads /prod/billing/database/password
03

How a name is built

Como um nome é montado

A secret name is joined from what the client knows and what the call asks for.

O nome do segredo é montado a partir do que o client sabe e do que a chamada pede.

env / project / prefix / name
/prod  /billing  /—       /database/password
/prod/billing/database/password

All three leading parts are optional: a client with none of them reads /database/password.

As três primeiras partes são opcionais: um client sem nenhuma delas lê /database/password.

PartParte Accepts a slashAceita barra RuleRegra
env NoNão The deployment context — prod, staging. A single segment. A slash here would silently add a level, and the caller would only find out through a secret that cannot be found. O contexto de deploy — prod, staging. Um único segmento. Uma barra aqui adicionaria um nível silenciosamente, e quem chamou só descobriria por um segredo que não é encontrado.
project NoNão Groups a set of secrets, usually one service or application. Same rule as env. Agrupa um conjunto de segredos, normalmente um serviço ou aplicação. Mesma regra do env.
prefix YesSim Adds any further levels you want. A string or a list of segments. A per-call prefix replaces the client's rather than adding to it. Adiciona quantos níveis você quiser. Uma string ou uma lista de segmentos. Um prefix por chamada substitui o do client em vez de somar a ele.
namename YesSim What the call asks for. Accepts /, because adding levels is exactly what it is for. O que a chamada pede. Aceita /, porque adicionar níveis é exatamente para isso que serve.
04

Changing the name for one call

Mudando o nome para uma chamada

Each of the three client-level parts can be dropped, and each can be replaced.

Cada uma das três partes do nível do client pode ser derrubada, e cada uma pode ser substituída.

Omitting always wins over replacing. Passing both omit_projectomitProject and project drops the segment.

Omitir sempre vence substituir. Passar omit_projectomitProject e project juntos derruba o segmento.

Replacing env is never implicit: the client's value applies unless a call says otherwise, in that call alone. It exists for the caller who knows better than the process context — a local run reading the one secret that lives elsewhere.

Substituir o env nunca é implícito: o valor do client vale a menos que uma chamada diga o contrário, e só naquela chamada. Existe para quem chama e sabe mais que o contexto do processo — uma execução local lendo o único segredo que mora em outro lugar.

per-call optionsopções por chamada
from secret_kernel.contracts import GetSecretOptions

# /prod/billing/database — the client prefix is left out
await client.get_secret(
    "database", GetSecretOptions(omit_prefix=True)
)

# /prod/shared/api-key — read another project's secret
await client.get_secret(
    "api-key", GetSecretOptions(project="shared")
)

# /staging/billing/database/password — another environment, once
await client.get_secret(
    "database/password", GetSecretOptions(env="staging")
)

# /license-key — belongs to no environment or project
await client.get_secret(
    "license-key",
    GetSecretOptions(omit_env=True, omit_project=True),
)
// /prod/billing/database — the client prefix is left out
await client.getSecret('database', { omitPrefix: true });

// /prod/shared/api-key — read another project's secret
await client.getSecret('api-key', { project: 'shared' });

// /staging/billing/database/password — another environment, once
await client.getSecret('database/password', { env: 'staging' });

// /license-key — belongs to no environment or project
await client.getSecret('license-key', {
  omitEnv: true,
  omitProject: true,
});
05

Reading structured secrets

Lendo segredos estruturados

A secret is a string by default. Ask for a parse mode and the value follows.

Um segredo é uma string por padrão. Peça um modo de parse e o valor acompanha.

Parse modes

Modos de parse

Two modes: JSON and KEY_VALUE. Keys and values are trimmed by default.

Dois modos: JSON e KEY_VALUE. Chaves e valores têm espaços removidos por padrão.

A secret that exists but cannot be parsed raises SecretParseError; parse results are never cached.

Um segredo que existe mas não pode ser parseado levanta SecretParseError; resultados de parse nunca são cacheados.

parseparse
from secret_kernel.contracts import (
    GetSecretOptions,
    SecretParseMode,
)

# "s3cr3t"
plain = await client.get_secret("database/password")

# {"host": "db.internal", "port": 5432}
config = await client.get_secret(
    "database/config", GetSecretOptions(parse=SecretParseMode.JSON)
)

# {"user": "app", "password": "s3cr3t"}
# from "user=app;password=s3cr3t"
pairs = await client.get_secret(
    "database/credentials",
    GetSecretOptions(parse=SecretParseMode.KEY_VALUE),
)
import { SecretParseMode } from '@secret-kernel/contracts';

// "s3cr3t"
const plain = await client.getSecret('database/password');

// { host: 'db.internal', port: 5432 }
type DbConfig = { host: string; port: number };

const config = await client.getSecret<DbConfig>(
  'database/config',
  { parse: SecretParseMode.Json },
);

// { user: 'app', password: 's3cr3t' }
// from "user=app;password=s3cr3t"
const pairs = await client.getSecret(
  'database/credentials',
  { parse: SecretParseMode.KeyValue },
);

Key-value conventions

Convenções chave-valor

If a project always stores key-value secrets the same way, set the convention once on the client instead of repeating it at every call.

Se um projeto sempre guarda segredos chave-valor do mesmo jeito, defina a convenção uma vez no client em vez de repeti-la em cada chamada.

A per-call parse_optionsparseOptions is merged over the client's field by field, so a call that needs one different separator does not have to restate the others.

Um parse_optionsparseOptions por chamada é mesclado sobre o do client campo por campo, então uma chamada que precisa de um separador diferente não precisa repetir os outros.

FieldCampo DefaultPadrão
pair_separatorpairSeparator";"
key_value_separatorkeyValueSeparator"="
keysempty — names positional values that carry no separatorvazio — nomeia valores posicionais que não trazem separador
trimTruetrue

Empty pairs are ignored, empty values are kept as "", an empty key raises, and a repeated key keeps the last value.

Pares vazios são ignorados, valores vazios são mantidos como "", uma chave vazia levanta erro, e uma chave repetida mantém o último valor.

set once on the clientdefinido uma vez no client
from secret_kernel.contracts import KeyValueParseOptions

client = create_secret_client(
    CreateSecretClientConfig(
        provider="aws-parameter-store",
        env="prod",
        parse_options=KeyValueParseOptions(
            pair_separator="|",
            key_value_separator=":",
        ),
        options=AwsParameterStoreProviderOptions(
            region="us-east-1",
        ),
    )
)

# only the pair separator differs here; ":" is inherited
await client.get_secret(
    "legacy",
    GetSecretOptions(
        parse=SecretParseMode.KEY_VALUE,
        parse_options=KeyValueParseOptions(pair_separator=";"),
    ),
)
const client = await createSecretClient({
  provider: SecretProvider.AwsParameterStore,
  env: 'prod',
  parseOptions: { pairSeparator: '|', keyValueSeparator: ':' },
  options: { region: 'us-east-1' },
});

// only the pair separator differs here; ':' is inherited
await client.getSecret('legacy', {
  parse: SecretParseMode.KeyValue,
  parseOptions: { pairSeparator: ';' },
});
06

Five providers, one call

Cinco providers, uma chamada

Provider options are typed per provider and never leak into the shared contract.

As opções de provider são tipadas por provider e nunca vazam para o contrato compartilhado.

Provider DistributionDistribuição Use forUsar para
in-memory secret-kernel-provider-in-memory@secret-kernel/provider-in-memory Local development, CI and tests. Reads preloaded values or environment variables. Desenvolvimento local, CI e testes. Lê valores pré-carregados ou variáveis de ambiente.
aws-parameter-store secret-kernel-provider-aws-parameter-store@secret-kernel/provider-aws-parameter-store Low-cost secrets in AWS, as SecureString parameters. Segredos de baixo custo na AWS, como parâmetros SecureString.
aws-secrets-manager secret-kernel-provider-aws-secrets-manager@secret-kernel/provider-aws-secrets-manager AWS secrets that need rotation and a dedicated lifecycle. Reads the AWSCURRENT stage; a binary-only secret raises SecretCapabilityNotSupportedError. Segredos da AWS que precisam de rotação e ciclo de vida próprio. Lê o estágio AWSCURRENT; um segredo apenas binário levanta SecretCapabilityNotSupportedError.
gcp-parameter-manager secret-kernel-provider-gcp-parameter-manager@secret-kernel/provider-gcp-parameter-manager Low-cost secrets in GCP. Takes a location, defaulting to global. Segredos de baixo custo no GCP. Recebe um location, com padrão global.
gcp-secret-manager secret-kernel-provider-gcp-secret-manager@secret-kernel/provider-gcp-secret-manager GCP secrets that need rotation and a dedicated lifecycle. Segredos do GCP que precisam de rotação e ciclo de vida próprio.

Credentials

Credenciais

Credentials are explicit when you pass them, and fall back to the cloud SDK's own chain when you do not. Explicit credentials take precedence.

As credenciais são explícitas quando você as passa, e caem para a própria cadeia do SDK da nuvem quando você não passa. Credenciais explícitas têm precedência.

Injecting a client keeps the SDK client under your lifecycle — the kernel closes only what it created.

Injetar um client mantém o client do SDK sob o seu ciclo de vida — o kernel fecha apenas o que ele mesmo criou.

Providers that cannot store / flatten the resolved name with a separator: AWS accepts /, _ and - and defaults to /; GCP accepts _ and - and defaults to _.

Providers que não conseguem guardar / achatam o nome resolvido com um separador: a AWS aceita /, _ e - e usa / como padrão; o GCP aceita _ e - e usa _.

gcp-secret-managergcp-secret-manager
from secret_kernel.provider_gcp_secret_manager import (
    GcpSecretManagerProviderOptions,
)

client = create_secret_client(
    CreateSecretClientConfig(
        provider="gcp-secret-manager",
        env="prod",
        project="billing",
        options=GcpSecretManagerProviderOptions(
            project_id="my-gcp-project",
            physical_name_separator="_",
        ),
    )
)

# reads projects/my-gcp-project/secrets/
#   prod_billing_database_password/versions/latest
const client = await createSecretClient({
  provider: SecretProvider.GcpSecretManager,
  env: 'prod',
  project: 'billing',
  options: {
    projectId: 'my-gcp-project',
    physicalNameSeparator: '_',
  },
});

// reads projects/my-gcp-project/secrets/
//   prod_billing_database_password/versions/latest
07

Caching

Cache

Reads hit the provider every time unless you enable the cache.

As leituras vão ao provider todas as vezes, a menos que você habilite o cache.

The cache stores the decrypted string keyed by the resolved name, before any parsing, so the same secret read as JSON and as text costs one provider call.

O cache guarda a string descriptografada chaveada pelo nome resolvido, antes de qualquer parse, então o mesmo segredo lido como JSON e como texto custa uma chamada ao provider.

A value served from cache reports no version and no metadata: the cache stores the string only.

Um valor servido do cache não reporta version nem metadata: o cache guarda apenas a string.

Failures are never cached. A missing secret that appears later is found on the next read.

Falhas nunca são cacheadas. Um segredo ausente que aparece depois é encontrado na leitura seguinte.

Encryption in memory

Criptografia em memória

For a process that holds secrets in memory for a long time, cached values can be encrypted with AES-256-GCM. Without an encryption_keyencryptionKey the client generates one and keeps it in memory only.

Para um processo que mantém segredos em memória por muito tempo, os valores cacheados podem ser criptografados com AES-256-GCM. Sem uma encryption_keyencryptionKey, o client gera uma e a mantém apenas em memória.

What it protects against: a heap snapshot, or an accidental object dump. What it does not: code running inside the same process.

Contra o que protege: um snapshot de heap, ou um dump acidental de objeto. Contra o que não protege: código rodando dentro do mesmo processo.

cachecache
from secret_kernel.contracts import SecretCacheOptions

client = create_secret_client(
    CreateSecretClientConfig(
        provider="aws-secrets-manager",
        env="prod",
        cache=SecretCacheOptions(
            enabled=True,
            ttl_ms=300_000,
            max_entries=100,
            encrypt_in_memory=True,
        ),
        options=AwsSecretsManagerProviderOptions(
            region="us-east-1",
        ),
    )
)
const client = await createSecretClient({
  provider: SecretProvider.AwsSecretsManager,
  env: 'prod',
  cache: {
    enabled: true,
    ttlMs: 300_000,
    maxEntries: 100,
    encryptInMemory: true,
  },
  options: { region: 'us-east-1' },
});
08

Errors are part of the contract

Erros fazem parte do contrato

Every error carries provider, secret_namesecretName, code, ref and cause.

Todo erro carrega provider, secret_namesecretName, code, ref e cause.

Only not-found and permission are normalized. Every other failure keeps the message the SDK produced and gains provider, ref and code, with the original exception in cause.

não-encontrado e permissão são normalizados. Toda outra falha preserva a mensagem que o SDK produziu e ganha provider, ref e code, com a exceção original em cause.

This is why a missing secret raises SecretNotFoundError whichever provider is behind the contract — and why a provider-specific failure still tells you which SDK produced it.

É por isso que um segredo ausente levanta SecretNotFoundError qualquer que seja o provider por trás do contrato — e por isso que uma falha específica de provider ainda diz qual SDK a produziu.

handlingtratamento
from secret_kernel.contracts import (
    SecretNotFoundError,
    SecretParseError,
)

try:
    secret = await client.get_secret(
        "database/config",
        GetSecretOptions(parse=SecretParseMode.JSON),
    )
except SecretNotFoundError as error:
    logger.warning("missing %s on %s", error.ref, error.provider)
    raise
except SecretParseError as error:
    logger.error(
        "unparseable %s", error.ref, exc_info=error.__cause__
    )
    raise
import {
  SecretNotFoundError, SecretParseError,
} from '@secret-kernel/contracts';

try {
  const secret = await client.getSecret('database/config', {
    parse: SecretParseMode.Json,
  });
} catch (error) {
  if (error instanceof SecretNotFoundError) {
    logger.warn(`missing ${error.ref} on ${error.provider}`);
  } else if (error instanceof SecretParseError) {
    logger.error(`unparseable ${error.ref}`, {
      cause: error.cause,
    });
  }
  throw error;
}
ClassClasse Raised whenLevantado quando
SecretNotFoundErrorThe secret or parameter does not exist.O segredo ou parâmetro não existe.
SecretPermissionErrorThe provider refused the read.O provider recusou a leitura.
SecretParseErrorThe secret was read but the requested parse failed.O segredo foi lido, mas o parse pedido falhou.
InvalidSecretNameErrorThe resolved name is empty or unusable.O nome resolvido está vazio ou inutilizável.
SecretCapabilityNotSupportedErrorThe provider cannot serve the request under the base contract.O provider não consegue atender ao pedido dentro do contrato base.
SecretConfigurationErrorRequired, invalid or mutually exclusive configuration.Configuração obrigatória, inválida ou mutuamente exclusiva.
SecretProviderErrorAny other provider failure.Qualquer outra falha do provider.
09

Observability, and your own provider

Observabilidade, e seu próprio provider

Silent unless you ask, and open to a store the kernel has never heard of.

Silencioso a menos que você peça, e aberto a um cofre que o kernel nunca viu.

Lifecycle events

Eventos de ciclo de vida

Pass a logger to receive lifecycle events, or debug to send them to the console. Without either, the client is silent.

Passe um logger para receber eventos de ciclo de vida, ou debug para mandá-los ao console. Sem nenhum dos dois, o client fica silencioso.

Bring your own provider

Traga seu próprio provider

The factory accepts a provider class directly, so a store this package has never heard of is used through the same contract. The factory asserts the class declares the requested provider_nameproviderName.

A factory aceita uma classe de provider diretamente, então um cofre que este pacote nunca viu é usado pelo mesmo contrato. A factory verifica que a classe declara o provider_nameproviderName pedido.

The shared contract suite in the testing package runs every portable guarantee against it — decrypted reads, prefix composition, both parse modes, and SecretNotFoundError on a missing secret.

A suíte de contrato compartilhada no pacote de testing roda todas as garantias portáveis contra ele — leituras descriptografadas, composição de prefix, os dois modos de parse, e SecretNotFoundError num segredo ausente.

logginglogging
client = create_secret_client(
    CreateSecretClientConfig(
        provider="gcp-secret-manager",
        env="prod",
        logger=my_logger,   # .debug(message, context)
        options=GcpSecretManagerProviderOptions(
            project_id="my-project",
        ),
    )
)
const client = await createSecretClient({
  provider: SecretProvider.GcpSecretManager,
  env: 'prod',
  logger: {
    debug: (message, context) => myLogger.debug(message, context),
  },
  options: { projectId: 'my-project' },
});
custom providerprovider customizado
create_secret_client(
    CreateSecretClientConfig(
        provider="my-vault",
        provider_class=MyVaultClient,
    )
)
await createSecretClient({
  provider: 'my-vault',
  providerClass: MyVaultClient,
});
10

Changelog

Changelog

Early, and honest about it. Each implementation releases on its own, so this follows the language you picked above. Within one release every distribution shares a version.

No começo, e honesto sobre isso. Cada implementação lança por conta própria, então isto acompanha a linguagem escolhida acima. Dentro de um release, toda distribuição compartilha a versão.

0.1.0a3 2026-08-27

Added

Adicionado

get_secret accepts an env that replaces the client's environment for one call. It is never implicit and never a default: the environment the client was built with applies unless a call says otherwise, in that call alone, and omit_env still wins over it.

get_secret aceita um env que substitui o ambiente do client por uma chamada. Nunca é implícito nem default: o ambiente com que o client foi construído vale a menos que uma chamada diga o contrário, e só naquela chamada, e o omit_env continua vencendo.

0.1.0a2 2026-08-25

Changed

Alterado

  • The API reference guard now checks both directions. It asserted that every export is documented and never that every documented name still exists, so a name that left the public surface stayed in the reference indefinitely.
  • The integration suites hand credentials to the provider instead of expecting them in the environment, the same way an application injects configuration — which also exercises the documented precedence of explicit credentials over the SDK chain.
  • O guard da referência de API agora checa nas duas direções. Ele afirmava que todo export está documentado e nunca que todo nome documentado ainda existe, então um nome que saiu da superfície pública ficava na referência indefinidamente.
  • As suítes de integração passam credenciais ao provider em vez de esperá-las no ambiente, do mesmo jeito que uma aplicação injeta configuração — o que também exercita a precedência documentada de credenciais explícitas sobre a cadeia do SDK.
0.1.0a1 first alpha primeiro alpha

The contract, the shared core, the factory, the five providers and the shared contract suite. Tagged before changelog fragments were being kept, which is why there is nothing itemised here.

O contrato, o core compartilhado, a factory, os cinco providers e a suíte de contrato compartilhada. Tagueado antes de os fragmentos de changelog começarem a ser mantidos, e é por isso que não há itens detalhados aqui.

0.1.0-alpha.3 unpublished não publicado

Added

Adicionado

getSecret accepts an env that replaces the client's environment for one call. It is never implicit and never a default: the environment the client was built with applies unless a call says otherwise, in that call alone, and omitEnv still wins over it.

getSecret aceita um env que substitui o ambiente do client por uma chamada. Nunca é implícito nem default: o ambiente com que o client foi construído vale a menos que uma chamada diga o contrário, e só naquela chamada, e o omitEnv continua vencendo.

0.1.0-alpha.1 first alpha primeiro alpha unpublished não publicado

The contract, the shared core, the factory, the five providers and the shared contract suite. Tagged and feature-complete against the same contract, but nothing was pushed to npm — read it from the repository until it is.

O contrato, o core compartilhado, a factory, os cinco providers e a suíte de contrato compartilhada. Tagueado e completo em features contra o mesmo contrato, mas nada foi enviado ao npm — leia direto do repositório até que seja.