Pular para o conteúdo

Dependências

Tudo que uma task exige do seu ambiente é declarado numa lista só, com tipo:

dependencies:
source: "." # diretório
gcpCredential: ./chaves/service-account.json # arquivo
gitToken: ${env.OREN_GIT_TOKEN} # valor sensível
docker: true # acesso concedido

A chave é definida pelo contrato — você não escolhe o nome, só como satisfazê-lo. O tipo de cada uma determina como o valor é entregue ao worker.

Forma Você fornece O worker recebe
directory caminho no host diretório montado
file caminho no host arquivo montado, modo 0400
string valor ou ${env.OREN_VAR} variável de ambiente
endpoint/tcp um endereço, host:<porta>, ou um provider <ENV>, <ENV>_HOST, <ENV>_PORT — veja Providers e endpoints

| socket | true | socket montado |

Cada tipo carrega um nível, e é isso que torna implementações comparáveis:

O nível tem um piso, calculado da forma e das flags, e ele não é negociável:

Declaração Piso
form: directory baixo
form: directory, mutable: true médio — escrever no seu working dir custa mais que ler
qualquer sensitive: true médio
form: capability (rede) médio
form: socket crítico — acesso ao socket equivale a root no host

Quem escreve o contrato pode declarar privilege acima do piso, nunca abaixo. Abaixo é erro de validação, não preferência.

A assimetria existe porque privilégio é o único campo do spec que quem declara se beneficia de subdeclarar: é ele que ranqueia implementações no catálogo. O piso tira do alcance de qualquer autor justamente a parte catastrófica — não há como anunciar um socket como barato.

Declarar acima é o caso legítimo, e vale quando o escopo é pior do que a forma revela: um token que alcança o time inteiro em vez de um recurso. É o que techlite/coolify-deploy faz:

coolifyToken:
form: string
sensitive: true
privilege: high
description: >-
Token da API com permissão de implantar. O escopo do token é o TIME e não a
aplicação: não existe emitir um que alcance só este recurso.

O nível descreve o que a credencial pode, não o que você pretende fazer com ela.

Ele também é criado se não existir. Um diretório mutável é onde o worker escreve, e exigir que ele já esteja lá quebraria toda primeira execução em cópia limpa — o .oren/artefatos de um CI que acabou de clonar não existe, e git não versiona diretório vazio.

Um diretório de leitura que não existe é o oposto: é engano de caminho, e o Oren recusa dizendo qual step e qual dependência. Criá-lo montaria um diretório vazio em silêncio, e o step falharia adiante, longe da causa.

Você não precisa guardar segredos em lugar nenhum novo. Se sua organização já usa Vault ou Secret Manager, buscar o segredo é só mais uma task:

- id: creds
task: acme/fetch-vault-secrets@^1.0.0
implementation: acme/fetch-vault-secrets-sh
inputs:
paths: [secret/data/gcp/prod]
dependencies:
vaultToken: ${env.OREN_VAULT_TOKEN}
- id: push
task: techlite/push-docker-image@^1.0.0
implementation: techlite/push-docker-image-skopeo
dependencies:
registryCredential: ${outputs['creds'].gcpServiceAccount}

Valores marcados como secretos nunca aparecem em log, nunca vão para o lockfile e nunca tocam o disco — a CLI materializa o conteúdo direto no container.

A marca é contagiosa: um campo comum que interpole um valor secreto passa a ser tratado como secreto.