Skip to main content

Deployment topology and License

This document describes ApiGo's production deployment structure and License authorization mechanism. Addresses, accounts, and secrets are always injected through environment variables or external configuration files; this document records no real values.

Deployment topology​

Component list​

ComponentRequiredDescription
MySQL 8.4+RequiredPlatform metadata; also stores call logs when ES is not enabled
Redis 7+RequiredRuntime configuration hub, Pub/Sub change notifications, distributed locks, response cache
Registry (Nacos 2.3+ or Eureka)Required for cluster deploymentService discovery, cluster node count probing; can be omitted for direct single-node connections
Elasticsearch 7+OptionalCall log search; once enabled, logs are no longer written to MySQL
apigo-adminRequiredAdmin APIs and configuration distribution
apigo-apiRequiredAPI execution engine
apigo-gatewayRequiredUnified entry point and governance
apigo-webRequiredStatic assets for the frontend portal

Startup order​

  1. MySQL, Redis, registry (and the optional Elasticsearch)
  2. apigo-admin
  3. apigo-api
  4. apigo-gateway
  5. apigo-web

At startup, the admin loads data sources and writes runtime configuration to Redis; the gateway depends on this data to build routes. If the order is reversed, the gateway may briefly have no routes and self-heals after the next reconciliation, but for first-time deployments you should still start the services in order.

Port conventions​

ServiceDefault port
apigo-admin9377
apigo-api9366
apigo-gateway9600
apigo-webNginx 80 (container maps 8080); Vite default 7000 in development mode

Open APIs all enter through the gateway at 9600; apigo-api is not exposed directly.

Configuration security​

The following configurations must be externalized and must not be written into the code repository or documentation:

  • Database address, account, password
  • Redis address and password
  • AI model API key
  • SMTP / SMS / Webhook credentials
  • License file and private key

We recommend injecting them through environment variables, a configuration center, or a mounted application-*.yml, and restricting file permissions. Data source passwords are stored encrypted with RSA/SM2 inside the platform, but this does not replace access control on configuration files.

License mechanism​

Protection scope​

apigo-admin, apigo-api, and apigo-gateway all depend on the apigo-license module. All three services validate authorization at startup; if any service fails validation, it cannot start.

Validation pipeline​

  1. Signature verification: verify the signature with the public key built into the release jar (trust anchor) to prevent forgery and tampering; development builds can specify it via apigo.license.public-key.
  2. Time window: the current time must fall between notBefore and notAfter.
  3. Service whitelist: when serviceIds is non-empty, the current service's spring.application.name must be in the list, preventing one License from working for all services.
  4. Typed validation: check the MAC or cluster node count according to the license type.
  5. Clock rollback: compare with the time watermark recorded in the state file; a rollback beyond the tolerance is treated as tampering.

Three license types​

TypeValidation contentApplicable scenarios
SIMPLETime window onlyDemos, PoC, fully dynamic environments
STANDARDTime + server MAC bindingSingle machine, physical machine, fixed cluster
CLUSTERTime + cluster node count range (no MAC check)Dynamic container environments such as Kubernetes and Swarm

For CLUSTER, the node count is max(registry instance count, configured lower bound). The configured value can only declare a lower bound; it cannot lower the actual probed count, preventing bypass of the node limit by changing configuration.

License payload​

FieldMeaning
licenseIdLicense ID (UUID)
licenseeLicensee name
productCodeProduct line code (optional)
typeSIMPLE / STANDARD / CLUSTER
algorithmSignature algorithm: RSA or SM2
issueAt / notBefore / notAfterIssue, effective, and expiry time (epoch seconds)
macsAuthorized MAC list (STANDARD)
maxNodes / minNodesNode count upper / lower limit (CLUSTER)
serviceIdsService whitelist (optional)

Key configuration​

ConfigurationDefaultDescription
apigo.license.enabledfalseCan be disabled only in development builds; enforced once the release package has a built-in trust anchor
apigo.license.license-file-External license file path; supports bare paths, file:, and classpath:
apigo.license.check-interval24hScheduled validation period, minimum 1 minute
apigo.license.clock-skew-tolerance24hClock rollback tolerance
apigo.license.state.file~/.apigo/license.stateRollback watermark state file
apigo.license.state.stricttrueRefuse to run when the state file is unavailable (fail-closed)
apigo.license.mac.primary-interfaceAuto-detectedPrimary network interface to validate
apigo.license.cluster.node-count1Licensed node count lower bound
apigo.license.cluster.on-provider-errorfailTerminate or alert when node probing fails
apigo.license.cluster.node-limit-actionfailTerminate or alert when the node count is out of range
The state file must be persisted

Container deployments must mount the directory containing state.file to a persistent volume. Losing the state file under strict=true makes the service refuse to start; this prevents bypassing clock rollback detection by deleting the state file.

Failure handling​

ScenarioBehavior
Startup validation failureException thrown; the process exits with a non-zero exit code
Scheduled runtime validation failureLogs ERROR and exits according to the graceful shutdown policy with exit code 1
Unexpected exceptions such as registry flappingLogs ERROR and retries on the next cycle without exiting immediately
Node count exceeds the upper limit and the policy is failTerminates; with warn, alerts and continues

Exit code 1 distinguishes authorization problems from a normal shutdown (0), making it easy for orchestration systems to recognize an authorization issue rather than an ordinary restart.

Error codes​

Error codeMeaning
L001License not configured
L002Invalid License format
L003Signature verification failed
L004Invalid public key configuration
L005Unsupported signature algorithm or missing dependency
L006License not yet effective
L007License expired
L008Server MAC does not match the license
L009Cluster node count exceeds the licensed maximum
L010System clock rollback detected
L011Current service is not covered by the license
L012State file validation failed (possible tampering)
L013State file unavailable
L014Cluster node count probe failed
L015Cluster node count below the licensed minimum

Operations checklist​

  • MySQL and Redis available, charset utf8mb4
  • db/mysql/ddl.sql and the necessary upgrade scripts executed
  • The three Java services use the same Redis and can reach each other over the network
  • License file mounted read-only; state directory writable and persistent
  • Services started in the correct order; the gateway can read routes
  • Frontend Nginx configured with an API reverse proxy and static asset caching
  • Logs, monitoring, and alerting channels connected