Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ona.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

Available on the Enterprise plan. Contact sales to learn more.
Ona environments can authenticate to HashiCorp Vault using the JWT auth method. The Ona CLI generates a JWT token that Vault validates against Ona’s OIDC discovery endpoint, then issues a Vault token with the policies you configure. No static Vault tokens or AppRole credentials are needed.

Prerequisites

Step 1: Enable the JWT auth method

Enable the JWT auth method in Vault and configure it to trust Ona’s OIDC endpoint:
vault auth enable jwt

vault write auth/jwt/config \
  oidc_discovery_url="https://app.gitpod.io" \
  default_role="ona-environment"
This tells Vault to fetch Ona’s signing keys from https://app.gitpod.io/.well-known/jwks.json and validate tokens against them.

Step 2: Create a Vault role

Create a role that defines which Ona tokens are accepted and what Vault policies they receive.

Organization-scoped role

Allow any environment in a specific Ona organization:
vault write auth/jwt/role/ona-environment \
  role_type="jwt" \
  bound_audiences="vault.hashicorp.com" \
  bound_claims='{"organization_id": "<ONA_ORG_ID>"}' \
  user_claim="sub" \
  token_policies="ona-read" \
  token_ttl="1h" \
  token_max_ttl="4h"

Project-scoped role

Restrict to environments from a specific project:
vault write auth/jwt/role/ona-project \
  role_type="jwt" \
  bound_audiences="vault.hashicorp.com" \
  bound_claims='{"organization_id": "<ONA_ORG_ID>", "project_id": "<ONA_PROJECT_ID>"}' \
  user_claim="sub" \
  token_policies="ona-read" \
  token_ttl="1h" \
  token_max_ttl="4h"

User-scoped role

Restrict to a specific user by email:
vault write auth/jwt/role/ona-dev \
  role_type="jwt" \
  bound_audiences="vault.hashicorp.com" \
  bound_claims='{"organization_id": "<ONA_ORG_ID>", "email": "dev@example.com"}' \
  user_claim="email" \
  token_policies="dev-secrets" \
  token_ttl="1h" \
  token_max_ttl="4h"

Role parameters

ParameterDescription
bound_audiencesMust match the --audience used in ona idp token. Default: vault.hashicorp.com
bound_claimsJSON object of claim-value pairs. All must match for authentication to succeed. Uses V3 flat claims.
user_claimThe token claim to use as the Vault identity alias. Common choices: sub, email, user_id
token_policiesVault policies to attach to the issued token
token_ttlInitial TTL of the Vault token
token_max_ttlMaximum TTL the token can be renewed to

Available V3 claims for bound_claims

You can bind on any V3 flat claim. Common choices:
  • organization_id - restrict to an Ona organization
  • project_id - restrict to a specific project
  • environment_id - restrict to a specific environment
  • user_id - restrict to a specific user
  • email - restrict by user email
  • creator_email - restrict by who created the environment
  • runner_id - restrict to environments on a specific runner
  • service_account_id - restrict to a specific service account

Step 3: Create a Vault policy

Create a policy that grants the access your environments need:
vault policy write ona-read - <<EOF
path "secret/data/my-app/*" {
  capabilities = ["read"]
}

path "secret/data/shared/*" {
  capabilities = ["read", "list"]
}
EOF

Step 4: Authenticate from an environment

Using the CLI shortcut

The Ona CLI has built-in Vault login support:
ona idp login vault --role ona-environment
This runs vault write auth/jwt/login under the hood and calls vault login with the resulting token. Options:
  • --role - the Vault role to authenticate against (defaults to IDP_VAULT_ROLE env var)
  • --audience - the token audience (default: vault.hashicorp.com)

Manual flow

If you need more control, use the Vault CLI directly:
TOKEN=$(ona idp token --audience vault.hashicorp.com)
vault write -format=json auth/jwt/login role=ona-environment jwt="$TOKEN"
Or as a one-liner that also logs in:
vault login -method=jwt role=ona-environment jwt="$(ona idp token --audience vault.hashicorp.com)"

Automate on environment startup

Add the login to your automations:
# automations.yaml
tasks:
  vault-login:
    name: Vault Login
    command: |
      ona idp login vault --role ona-environment
    triggeredBy:
      - postDevcontainerStart
After authentication, read secrets normally:
vault kv get secret/my-app/database

Using the Vault SDK

For programmatic access in your application:
import (
    vault "github.com/hashicorp/vault/api"
    "os/exec"
)

func vaultClient() (*vault.Client, error) {
    client, err := vault.NewClient(vault.DefaultConfig())
    if err != nil {
        return nil, err
    }

    // Get Ona OIDC token
    out, err := exec.Command("ona", "idp", "token",
        "--audience", "vault.hashicorp.com").Output()
    if err != nil {
        return nil, err
    }

    // Authenticate with Vault
    secret, err := client.Logical().Write("auth/jwt/login", map[string]interface{}{
        "role": "ona-environment",
        "jwt":  string(out),
    })
    if err != nil {
        return nil, err
    }

    client.SetToken(secret.Auth.ClientToken)
    return client, nil
}

Using V2 tokens with Vault

V2 tokens also work with Vault’s JWT auth method. V2 tokens include org and gsub claims instead of the flat V3 claims. Use bound_claims on org for organization-scoped access:
vault write auth/jwt/role/ona-v2 \
  role_type="jwt" \
  bound_audiences="vault.hashicorp.com" \
  bound_claims='{"org": "<ONA_ORG_ID>"}' \
  user_claim="sub" \
  token_policies="ona-read" \
  token_ttl="1h"
V2 tokens do not include email, project_id, or other flat claims, so fine-grained access control is limited to matching the sub claim. See the OIDC overview V2 section for the full V2 token reference.

Further reading

Troubleshooting

  • The bound_audiences in the Vault role must match the --audience used in ona idp token.
  • Default audience for Vault: vault.hashicorp.com.
  • The bound_claims values must exactly match the claims in your Ona token.
  • Decode your token: ona idp token --audience vault.hashicorp.com --decode
  • Verify the claim values match what you configured in the Vault role.
  • Vault cannot reach https://app.gitpod.io/.well-known/openid-configuration.
  • Verify network connectivity from your Vault server to app.gitpod.io.
  • The Vault token was issued, but the attached policies do not grant access to the requested path.
  • Check the token_policies on the Vault role and the policy definitions.