{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "access": { "type": "object", "properties": { "sshTunnel": { "type": "object", "properties": { "hostPort": { "type": "integer", "minimum": 1024, "maximum": 65535 } }, "additionalProperties": false } }, "additionalProperties": false }, "autoDeploy": { "type": "boolean" }, "backup": { "type": "object", "properties": { "integration": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" }, "gcs": { "type": "object", "properties": { "bucket": { "type": "string", "pattern": "^(?!\\d+\\.\\d+\\.\\d+\\.\\d+$)[a-z0-9][a-z0-9._-]{1,61}[a-z0-9]$" }, "prefix": { "type": "string", "maxLength": 512 }, "region": { "type": "string", "minLength": 1, "maxLength": 64 } }, "additionalProperties": false }, "restoreFrom": { "type": "string", "enum": ["s3", "gcs"] }, "retention": { "type": "object", "properties": { "keepLast": { "type": "integer", "minimum": 1, "maximum": 100 } }, "additionalProperties": false }, "s3": { "type": "object", "properties": { "bucket": { "type": "string", "pattern": "^(?!\\d+\\.\\d+\\.\\d+\\.\\d+$)[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$" }, "encryption": { "type": "string", "enum": ["AES256", "aws:kms"] }, "kmsKeyId": { "type": "string", "minLength": 1, "maxLength": 2048 }, "prefix": { "type": "string", "maxLength": 512 }, "region": { "type": "string", "minLength": 1, "maxLength": 64 } }, "additionalProperties": false }, "schedule": { "type": "object", "properties": { "cron": { "type": "string", "minLength": 1, "maxLength": 120 }, "timezone": { "type": "string", "const": "UTC" } }, "additionalProperties": false } }, "additionalProperties": false }, "notifications": { "type": "object", "properties": { "email": { "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "deployments": { "type": "boolean" }, "deploymentFailures": { "type": "boolean" }, "backupsAndRestores": { "type": "boolean" }, "alertsAndIncidents": { "type": "boolean" }, "address": { "type": "string", "maxLength": 320, "format": "email", "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" } }, "required": [ "deployments", "backupsAndRestores", "alertsAndIncidents", "address" ], "additionalProperties": false } }, "slack": { "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "deployments": { "type": "boolean" }, "deploymentFailures": { "type": "boolean" }, "backupsAndRestores": { "type": "boolean" }, "alertsAndIncidents": { "type": "boolean" }, "channelId": { "type": "string", "pattern": "^[A-Z][A-Z0-9]{1,79}$" } }, "required": [ "deployments", "backupsAndRestores", "alertsAndIncidents", "channelId" ], "additionalProperties": false } }, "discord": { "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "deployments": { "type": "boolean" }, "deploymentFailures": { "type": "boolean" }, "backupsAndRestores": { "type": "boolean" }, "alertsAndIncidents": { "type": "boolean" }, "webhookId": { "type": "string", "pattern": "^\\d{1,20}$" } }, "required": [ "deployments", "backupsAndRestores", "alertsAndIncidents", "webhookId" ], "additionalProperties": false } }, "telegram": { "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "deployments": { "type": "boolean" }, "deploymentFailures": { "type": "boolean" }, "backupsAndRestores": { "type": "boolean" }, "alertsAndIncidents": { "type": "boolean" }, "chatId": { "type": "string", "pattern": "^-?\\d{1,20}$" }, "messageThreadId": { "type": "integer", "exclusiveMinimum": 0, "maximum": 2147483647 } }, "required": [ "deployments", "backupsAndRestores", "alertsAndIncidents", "chatId" ], "additionalProperties": false } } }, "additionalProperties": false }, "externalSecrets": { "oneOf": [ { "type": "object", "properties": { "integration": { "type": "string", "const": "infisical" }, "project": { "type": "string", "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" }, "environmentSlug": { "type": "string", "minLength": 1, "maxLength": 128 }, "secretPath": { "type": "string", "minLength": 1, "maxLength": 1024 } }, "required": ["integration", "project"], "additionalProperties": false }, { "type": "object", "properties": { "integration": { "type": "string", "const": "doppler" }, "project": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[a-z0-9][a-z0-9-]*$" }, "config": { "type": "string", "minLength": 1, "maxLength": 128 } }, "required": ["integration", "project"], "additionalProperties": false } ] }, "ingress": { "oneOf": [ { "type": "object", "properties": { "type": { "type": "string", "const": "proxy" } }, "required": ["type"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "cloudflare-tunnel" }, "integration": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" }, "tunnel": { "type": "string", "minLength": 1, "maxLength": 128 }, "access": { "default": false, "type": "boolean" } }, "required": ["type", "integration"], "additionalProperties": false } ] }, "id": { "type": "string", "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$" }, "name": { "type": "string", "minLength": 1, "maxLength": 120 }, "description": { "type": "string", "maxLength": 500 }, "type": { "type": "string", "enum": [ "postgres", "mysql", "mariadb", "mongodb", "redis", "dragonfly", "keydb", "clickhouse" ] }, "image": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._/:@-]{0,511}$" }, "server": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string" }, "container": { "type": "object", "properties": { "network": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$" }, "networkAlias": { "type": "string", "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$" }, "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, "resources": { "type": "object", "properties": { "cpus": { "type": "number", "exclusiveMinimum": 0, "maximum": 128 }, "memory": { "type": "string", "pattern": "^\\d+(?:\\.\\d+)?[bkmg]$" } }, "additionalProperties": false }, "volumes": { "maxItems": 20, "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$" }, "mountPath": { "type": "string", "minLength": 1, "maxLength": 1024 } }, "required": ["name", "mountPath"], "additionalProperties": false } } }, "additionalProperties": false }, "health": { "type": "object", "properties": { "type": { "type": "string", "enum": ["command", "container", "http"] }, "path": { "type": "string", "maxLength": 1024, "pattern": "^\\/.*" }, "command": { "minItems": 1, "maxItems": 64, "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 4096 } }, "timeoutSeconds": { "type": "integer", "minimum": 5, "maximum": 600 } }, "additionalProperties": false }, "domains": { "type": "object", "properties": { "primary": { "type": "string", "minLength": 1, "maxLength": 253 }, "redirects": { "maxItems": 20, "type": "array", "items": { "type": "object", "properties": { "host": { "type": "string", "minLength": 1, "maxLength": 253 }, "status": { "anyOf": [ { "type": "number", "const": 301 }, { "type": "number", "const": 302 } ] } }, "required": ["host"], "additionalProperties": false } } }, "additionalProperties": false }, "tls": { "type": "object", "properties": { "mode": { "type": "string", "enum": ["direct", "cloudflare-dns"] } }, "additionalProperties": false }, "secrets": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "runtime": { "default": [], "maxItems": 200, "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 1024, "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" } } }, "additionalProperties": false }, "environments": { "type": "object", "propertyNames": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string", "pattern": "^[a-z][a-z0-9-]{0,62}$", "not": { "enum": [ "preview", "previews", "__proto__", "constructor", "prototype" ] } }, "additionalProperties": { "type": "object", "properties": { "access": { "type": "object", "properties": { "sshTunnel": { "type": "object", "properties": { "hostPort": { "type": "integer", "minimum": 1024, "maximum": 65535 } }, "additionalProperties": false } }, "additionalProperties": false }, "autoDeploy": { "type": "boolean" }, "backup": { "type": "object", "properties": { "integration": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" }, "gcs": { "type": "object", "properties": { "bucket": { "type": "string", "pattern": "^(?!\\d+\\.\\d+\\.\\d+\\.\\d+$)[a-z0-9][a-z0-9._-]{1,61}[a-z0-9]$" }, "prefix": { "type": "string", "maxLength": 512 }, "region": { "type": "string", "minLength": 1, "maxLength": 64 } }, "additionalProperties": false }, "restoreFrom": { "type": "string", "enum": ["s3", "gcs"] }, "retention": { "type": "object", "properties": { "keepLast": { "type": "integer", "minimum": 1, "maximum": 100 } }, "additionalProperties": false }, "s3": { "type": "object", "properties": { "bucket": { "type": "string", "pattern": "^(?!\\d+\\.\\d+\\.\\d+\\.\\d+$)[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$" }, "encryption": { "type": "string", "enum": ["AES256", "aws:kms"] }, "kmsKeyId": { "type": "string", "minLength": 1, "maxLength": 2048 }, "prefix": { "type": "string", "maxLength": 512 }, "region": { "type": "string", "minLength": 1, "maxLength": 64 } }, "additionalProperties": false }, "schedule": { "type": "object", "properties": { "cron": { "type": "string", "minLength": 1, "maxLength": 120 }, "timezone": { "type": "string", "const": "UTC" } }, "additionalProperties": false } }, "additionalProperties": false }, "notifications": { "type": "object", "properties": { "email": { "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "deployments": { "type": "boolean" }, "deploymentFailures": { "type": "boolean" }, "backupsAndRestores": { "type": "boolean" }, "alertsAndIncidents": { "type": "boolean" }, "address": { "type": "string", "maxLength": 320, "format": "email", "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" } }, "required": [ "deployments", "backupsAndRestores", "alertsAndIncidents", "address" ], "additionalProperties": false } }, "slack": { "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "deployments": { "type": "boolean" }, "deploymentFailures": { "type": "boolean" }, "backupsAndRestores": { "type": "boolean" }, "alertsAndIncidents": { "type": "boolean" }, "channelId": { "type": "string", "pattern": "^[A-Z][A-Z0-9]{1,79}$" } }, "required": [ "deployments", "backupsAndRestores", "alertsAndIncidents", "channelId" ], "additionalProperties": false } }, "discord": { "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "deployments": { "type": "boolean" }, "deploymentFailures": { "type": "boolean" }, "backupsAndRestores": { "type": "boolean" }, "alertsAndIncidents": { "type": "boolean" }, "webhookId": { "type": "string", "pattern": "^\\d{1,20}$" } }, "required": [ "deployments", "backupsAndRestores", "alertsAndIncidents", "webhookId" ], "additionalProperties": false } }, "telegram": { "maxItems": 100, "type": "array", "items": { "type": "object", "properties": { "deployments": { "type": "boolean" }, "deploymentFailures": { "type": "boolean" }, "backupsAndRestores": { "type": "boolean" }, "alertsAndIncidents": { "type": "boolean" }, "chatId": { "type": "string", "pattern": "^-?\\d{1,20}$" }, "messageThreadId": { "type": "integer", "exclusiveMinimum": 0, "maximum": 2147483647 } }, "required": [ "deployments", "backupsAndRestores", "alertsAndIncidents", "chatId" ], "additionalProperties": false } } }, "additionalProperties": false }, "externalSecrets": { "oneOf": [ { "type": "object", "properties": { "integration": { "type": "string", "const": "infisical" }, "project": { "type": "string", "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" }, "environmentSlug": { "type": "string", "minLength": 1, "maxLength": 128 }, "secretPath": { "type": "string", "minLength": 1, "maxLength": 1024 } }, "required": ["integration", "project"], "additionalProperties": false }, { "type": "object", "properties": { "integration": { "type": "string", "const": "doppler" }, "project": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[a-z0-9][a-z0-9-]*$" }, "config": { "type": "string", "minLength": 1, "maxLength": 128 } }, "required": ["integration", "project"], "additionalProperties": false } ] }, "ingress": { "oneOf": [ { "type": "object", "properties": { "type": { "type": "string", "const": "proxy" } }, "required": ["type"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "cloudflare-tunnel" }, "integration": { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" }, "tunnel": { "type": "string", "minLength": 1, "maxLength": 128 }, "access": { "default": false, "type": "boolean" } }, "required": ["type", "integration"], "additionalProperties": false } ] }, "description": { "type": "string", "maxLength": 500 }, "image": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._/:@-]{0,511}$" }, "server": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "string" }, "container": { "type": "object", "properties": { "network": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$" }, "networkAlias": { "type": "string", "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$" }, "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, "resources": { "type": "object", "properties": { "cpus": { "type": "number", "exclusiveMinimum": 0, "maximum": 128 }, "memory": { "type": "string", "pattern": "^\\d+(?:\\.\\d+)?[bkmg]$" } }, "additionalProperties": false }, "volumes": { "maxItems": 20, "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$" }, "mountPath": { "type": "string", "minLength": 1, "maxLength": 1024 } }, "required": ["name", "mountPath"], "additionalProperties": false } } }, "additionalProperties": false }, "health": { "type": "object", "properties": { "type": { "type": "string", "enum": ["command", "container", "http"] }, "path": { "type": "string", "maxLength": 1024, "pattern": "^\\/.*" }, "command": { "minItems": 1, "maxItems": 64, "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 4096 } }, "timeoutSeconds": { "type": "integer", "minimum": 5, "maximum": 600 } }, "additionalProperties": false }, "domains": { "type": "object", "properties": { "primary": { "type": "string", "minLength": 1, "maxLength": 253 }, "redirects": { "maxItems": 20, "type": "array", "items": { "type": "object", "properties": { "host": { "type": "string", "minLength": 1, "maxLength": 253 }, "status": { "anyOf": [ { "type": "number", "const": 301 }, { "type": "number", "const": 302 } ] } }, "required": ["host"], "additionalProperties": false } } }, "additionalProperties": false }, "tls": { "type": "object", "properties": { "mode": { "type": "string", "enum": ["direct", "cloudflare-dns"] } }, "additionalProperties": false } }, "additionalProperties": false } } }, "additionalProperties": false, "required": ["id", "name", "type", "environments"], "description": "Entity defaults are merged with the selected environment before full validation during sync. Branch mappings and secret values are managed in Towbar.", "$id": "https://raw.githubusercontent.com/avgeek-inc/towbar/main/packages/towbar-core/schemas/resource.v2.json" }