Service Dependencies & Scopes

Scopes control how services access other services' databases and APIs. Most cross-service API calls need no scope grant — you just declare the dependency under spec.dependencies and the builder injects the URL. Scopes are required only when the target service defines Bio-ID scope grants (e.g. relay:send, raterspot:rate); the grant is then created automatically (same-org auto-approves, cross-org needs approval).

Overview

Access typeGrant systemWhat's sharedDeclared in
Database accessKoko scope grantsConnection strings (MongoDB, Redis, Neo4j)spec.scopes (owner) + CLI request (consumer)
API accessBio-ID scope grantsAuthenticated service-to-service API callsspec.dependencies (consumer)

No unauthenticated cross-service connections. Every dependency goes through an approval gate.

Database Access (Koko Grants)

Services can share database access through Koko's scope system. The owner declares what it shares, a consumer requests access, and an org admin approves.

1. Declare available scopes (owner)

spec:
  scopes:
    - resource: mongodb
      database: shared-data
      allowedConsumers:
        - service: my-consumer
          access: readOnly

Only services listed in allowedConsumers can request access.

2. Request access (consumer)

tawa scopes request --from owner-service --resource mongodb --access readOnly

3. On next deploy

The builder injects a connection string as an environment variable in the consumer service.

Access levels

LevelDescription
readWriteFull CRUD on MongoDB, all Redis commands, full Neo4j access
readOnlyMongoDB read preference enforced, Redis GET only, Neo4j read-only transactions

Environment variables

The owner service name is uppercased with hyphens replaced by underscores:

SHARED_DATA_SVC_MONGODB_URI=mongodb://host:27017/shared-data

Your service's own MONGODB_URI is unaffected — scoped variables always include the owner service name as a prefix.

API Access (Bio-ID Scope Grants)

For service-to-service API calls, declare the target under spec.dependencies. transport defaults to janus and scopes are optional — add scopes only when the target defines Bio-ID scope grants:

spec:
  dependencies:
    - service: raterspot
      scopes: [raterspot:rate]   # optional — only when the target defines scopes
      # transport omitted → defaults to janus (metered, JWT-verified via /i/)

A scoped dependency also provisions OAuth client-credentials (BIO_CLIENT_ID/BIO_CLIENT_SECRET) and opens a Bio-ID scope grant — same-org auto-approves, cross-org blocks the build until approved. See the catalog-info.yaml reference for the full dependency model.

Transport Modes

TransportInjects {SERVICE}_URL asGas meteredUse for
janus (default){JANUS_URL}/i/{service}YesAlmost everything — JWT-verified
directraw K8s DNS http://{svc}.{svc}-{env}…NoSame-org own-service UI/API splits only
gateway(no URL injected)YesCalling the Janus public gateway directly

transport defaults to janus — you rarely set it. direct only stays direct for same-org callers; a cross-org direct declaration is silently rerouted through Janus.

CLI Commands

# Request database access from another service
tawa scopes request --from owner-service --resource mongodb --access readOnly

# List pending and approved scope requests
tawa scopes list

# Approve an incoming scope request (org admin)
tawa scopes approve <request-id>

# Deny an incoming scope request
tawa scopes deny <request-id>

# Revoke previously granted access
tawa scopes revoke <request-id>

Common Patterns

Shared read-only analytics database

# owner-service catalog-info.yaml
spec:
  scopes:
    - resource: mongodb
      database: analytics
      allowedConsumers:
        - service: reporting-service
          access: readOnly

Multi-service event queue sharing

# owner-service catalog-info.yaml
spec:
  scopes:
    - resource: redis
      allowedConsumers:
        - service: worker-service
          access: readWrite

Last updated: June 24, 2026