Skip to main content

Provider

A Provider gives an agent access to an external service — GitHub, Telegram, AWS, GCP, Azure, Slack, or any HTTP API. The agent's requests to that service are transparently intercepted by the Pai sidecar, which injects credentials and enforces policy.

The agent never holds real credentials. It makes requests normally, and Pai handles authentication behind the scenes.

pai apply -f provider.yaml
pai get services
pai delete service <name>

How it works

When a provider is attached to an agent:

  1. DNS for the provider's hostname resolves to 127.0.0.1 (the sidecar) inside the agent pod
  2. The sidecar intercepts the HTTPS request
  3. Policy is checked — if denied, the request is blocked with HTTP 403
  4. Credentials are injected (Bearer token, SigV4 signature, OAuth2 token, etc.)
  5. The real request is forwarded to the external service

Field reference

FieldRequiredDescription
typeYesProvider type (see below)
hostNoHostname to intercept. Defaults to the provider's standard host
auth.typeYesAuthentication method
auth.secretRefYesName of the Secret holding credentials
auth.secretKeyNoKey within the Secret (default: token)
auth.agentEnvVarNoEnv var injected into the agent with a dummy value so libraries initialize correctly
config.regionNoCloud region (AWS, Azure)
config.projectNoGCP project ID
config.tenantIdNoAzure AD tenant ID
config.servicesNoRestrict to specific cloud services (e.g. [s3, sqs])
policy.allowNoAllowed actions. ["*"] = allow all
policy.denyNoDenied actions (takes precedence over allow)
policy.httpRulesNoRaw HTTP method + path rules (see below)
scope.repositoriesNoAllowed GitHub repositories
scope.channelsNoAllowed Slack channels
scope.resourcesNoAllowed cloud resource patterns (ARNs, paths)
audit.logRequestsNoLog every API call (default: true)
audit.enforcementNoenforce (default) blocks violations · audit logs but allows — useful for testing a new policy

Provider types

typeauth.typeDescription
githubpatGitHub Personal Access Token
telegrambot-tokenTelegram Bot API
slackbot-tokenSlack Bot token
awsaws-sigv4AWS SigV4 request signing
azureazure-client-credentialsAzure OAuth2 client credentials
gcpgcp-service-accountGCP service account JSON key

Examples

GitHub

apiVersion: pai.io/v1
kind: Provider
metadata:
name: github-writer
spec:
type: github
auth:
type: pat
secretRef: github-pat
policy:
allow:
- pulls:create
- pulls:comment
- issues:read
- contents:read
deny:
- admin:*
scope:
repositories:
- "myorg/repo-a"
- "myorg/repo-b"

Secret required:

pai add secret github-pat --from-literal token=ghp_YOUR_TOKEN

Telegram

apiVersion: pai.io/v1
kind: Provider
metadata:
name: telegram-bot
spec:
type: telegram
host: api.telegram.org
auth:
type: bot-token
secretRef: telegram-token
secretKey: token
agentEnvVar: TELEGRAM_BOT_TOKEN
policy:
allow: ["*"]

Secret required:

pai add secret telegram-token --from-literal token=YOUR_BOT_TOKEN

AWS S3

apiVersion: pai.io/v1
kind: Provider
metadata:
name: s3-reader
spec:
type: aws
auth:
type: aws-sigv4
secretRef: aws-creds
config:
region: us-east-1
services: [s3]
policy:
allow:
- s3:GetObject
- s3:ListBucket
deny:
- s3:DeleteObject
- s3:PutObject
scope:
resources:
- "arn:aws:s3:::my-bucket/*"

Secret required:

pai add secret aws-creds \
--from-literal access_key_id=AKIAIOSFODNN7EXAMPLE \
--from-literal secret_access_key=wJalrXUtnFEMI...

GCP

apiVersion: pai.io/v1
kind: Provider
metadata:
name: gcp-storage
spec:
type: gcp
auth:
type: gcp-service-account
secretRef: gcp-sa-key
config:
project: my-gcp-project
services: [storage]
policy:
allow:
- storage.objects.get
- storage.objects.list
deny:
- storage.objects.delete

Secret required:

pai add secret gcp-sa-key --from-literal key.json="$(cat service-account.json)"

Azure

apiVersion: pai.io/v1
kind: Provider
metadata:
name: azure-storage
spec:
type: azure
auth:
type: azure-client-credentials
secretRef: azure-sp-creds
config:
tenantId: "your-tenant-id"
services: [storage]
policy:
allow:
- "Microsoft.Storage/storageAccounts/read"
deny:
- "Microsoft.Storage/storageAccounts/delete"

Secret required:

pai add secret azure-sp-creds \
--from-literal client_id=YOUR_CLIENT_ID \
--from-literal client_secret=YOUR_CLIENT_SECRET

Attaching a provider to an agent

spec:
providers:
- github-writer
- telegram-bot

Policy

Action-based policy

Action names follow provider conventions:

ProviderFormatExamples
GitHubresource:actionpulls:create, issues:read, admin:*
AWSservice:Actions3:GetObject, sqs:SendMessage
AzureProvider/resource/actionMicrosoft.Storage/storageAccounts/read
GCPservice.resource.actionstorage.objects.get
Telegrammethod namesendMessage, getUpdates

HTTP-level rules

Use httpRules for fine-grained path/method control, or for services without a provider plugin:

policy:
allow: ["*"]
httpRules:
- methods: [GET]
paths: ["/repos/*/issues", "/repos/*/pulls"]
effect: allow
- methods: [POST, PUT, PATCH, DELETE]
paths: ["*"]
effect: deny

Deny rules are checked first. If httpRules is defined but no rule matches, the request is denied.

Audit mode

Roll out a new policy safely without blocking live traffic:

audit:
logRequests: true
enforcement: audit # switch to "enforce" once you're confident

Policy changes (policy, httpRules, audit, scope) take effect on running agents within ~1 minute without a restart.