Deployment guide

OpenAPI Generator 7.26.0

Overview

OpenAPI Generator turns an OpenAPI (Swagger) specification into working code: client SDKs for 89 languages and frameworks, server stubs for 73, and documentation sets. This image runs OpenAPI Generator Online, the service form of the project. It gives you a REST API that your build pipelines can call, plus an interactive console in the browser.

You send the service a specification, either in the request body or as a URL it fetches, and it returns a zip of generated code. Running it yourself keeps internal API descriptions inside your own network and gives every team the same generator version.

This guide covers launching and using the OpenAPI Generator 7.26.0 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud developer and API tools listing on AWS Marketplace. You pick it as the software version when you subscribe and launch.

What you get:

  • HTTPS from the first boot. nginx serves the generator on port 443 with a certificate generated on your instance's first boot. Port 80 only redirects to HTTPS.
  • A password gate in front of everything. The upstream service has no authentication at all. Every path (the console, the API, the OpenAPI document and the archive download) sits behind an HTTP Basic Auth prompt. Its password is generated on your instance's first boot.
  • No default login. The image contains no password, no certificate and no host name. First boot writes the gate's user name and a random 32-character password to /var/lib/sac/data/openapi-generator-credentials.txt (root only). nginx stores only a SHA-512 crypt hash and removes the password from every request before the generator sees it.
  • Spec fetching cannot reach inside your AWS account. The generator fetches the specification URLs you give it. Its service is blocked at the kernel level from the EC2 instance metadata service (IPv4 and IPv6), from every private (RFC 1918) address in your VPC and from this instance's own loopback services. Public specification URLs keep working.
  • Other web sites cannot act with your login. A browser re-sends the gate password to any site that asks. nginx therefore refuses every cross-site POST and every cross-site request to the download route, which deletes the archive it serves.
  • A rebuilt, current web stack. The upstream jar is built on Spring Boot 2.5, which is end of life. The image rebuilds it with current same-line releases of its web libraries (Apache Tomcat 9.0.123, Spring Framework 5.3.39, Jackson 2.21.8, Logback 1.2.13, SnakeYAML 2.4 and Commons Lang 3.18.0), each pinned by checksum. The rebuilt jar also fixes the upstream jar's broken Python client generation.
  • A locked-in generator. It listens on 127.0.0.1:8080 only and runs as its own unprivileged user. Its file system is read-only apart from its output directory, and it cannot read the gate password, the TLS key or the credentials file. Generated archives are cleaned up hourly once their download link has expired, with a 2 GB cap.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: OpenAPI Generator Online 7.26.0 (/opt/openapi-generator/), OpenJDK 21, nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. Settings are in /etc/openapi-generator/. The build record is in /usr/share/doc/sac-openapi-generator/.

Default user: ubuntu
Architecture: x86_64
Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet.
  • A security group that allows TCP 22 (SSH), TCP 443 (OpenAPI Generator) and TCP 80 (redirects to HTTPS). Open these ports to your own networks only.
1

Launch the instance

In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick OpenAPI Generator 7.26.0 on Ubuntu 24.04 as the software version and select your Region. Then choose Launch through EC2.

Choose m5.large, your key pair, a security group as described above and a subnet.

To launch with the AWS CLI instead, replace the values in angle brackets:

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=openapi-generator}]'
2

Connect to your instance

For OpenAPI Generator 7.26.0 on Ubuntu 24.04, the SSH user is ubuntu. Connect with your key pair:

ssh -i <your-key.pem> ubuntu@<public-ip>
3

Check the services

First boot takes about a minute. It generates the certificate and the password, then starts the generator and nginx. Check that everything is running:

systemctl is-active openapi-generator nginx openapi-generator-firstboot openapi-generator-egress-guard
sudo test -f /var/lib/sac/data/openapi-generator-firstboot.done && echo FIRSTBOOT_DONE
active active active active FIRSTBOOT_DONE

Only SSH and nginx listen on the network. The generator itself listens on loopback:

sudo ss -lntp | awk 'NR>1 {print $4, $6}' | grep -v '127.0.0.5' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g' | sort -u
0.0.0.0:22 users:(("sshd"),("systemd")) 0.0.0.0:443 users:(("nginx"),("nginx"),("nginx")) 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx")) [::]:22 users:(("sshd"),("systemd")) [::]:443 users:(("nginx"),("nginx"),("nginx")) [::]:80 users:(("nginx"),("nginx"),("nginx")) [::ffff:127.0.0.1]:8080 users:(("java"))
4

Get your URL and password

Run sudo cat /var/lib/sac/data/openapi-generator-credentials.txt to see your console URL, user name and password. The file is readable by root only. It holds the following settings, all generated for this instance, plus the SHA-256 fingerprint of its certificate:

sudo sed -n 's/^\(OAG_[A-Z0-9_]*\)=.*/\1/p' /var/lib/sac/data/openapi-generator-credentials.txt
OAG_URL OAG_HOST OAG_AUTH_USER OAG_AUTH_PASSWORD OAG_TLS_CERT OAG_TLS_SHA256_FINGERPRINT

The certificate is self-signed and generated on your instance. When your browser warns about it, compare the fingerprint it shows with OAG_TLS_SHA256_FINGERPRINT before you continue.

Do not add the certificate to a trust store. To remove the warning, give the instance a domain name and a CA-issued certificate (Step 9).

5

Use the console

Open OAG_URL (https://<public-ip>/) in a browser and sign in with OAG_AUTH_USER and OAG_AUTH_PASSWORD. The console lists every operation of the generation API.

Open POST /api/gen/clients/{language} to see the request it takes. The target language goes in the path. The JSON body carries either the specification itself in spec or a URL to fetch it from in openAPIUrl, plus generator options.

Select TRY to send the request from your browser through the same password gate. For example, it can list the client generators.

The console only ever loads this server's own API description. Loading another specification into it is switched off.

6

Generate code from the command line

Call the API from scripts and CI pipelines. These commands run on the instance. From your own machine, use https://<public-ip> with your user name and password in the same way.

The helper writes the credentials into a curl config on the fly, so the password never appears on a command line. First, list the available generators:

H=$(sudo sed -n 's/^OAG_HOST=//p' /var/lib/sac/data/openapi-generator-credentials.txt) gate() {
sudo awk -F= '/^OAG_AUTH_USER=/{u=$2} /^OAG_AUTH_PASSWORD=/{p=$2} END{printf "user = \"%s:%s\"\n", u, p}' /var/lib/sac/data/openapi-generator-credentials.txt; } OAG=(curl -s --cacert /etc/ssl/openapi-generator/openapi-generator.crt --resolve "$H:443:127.0.0.1") "${OAG[@]}" -K <(gate) "https://$H/api/gen/clients" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(len(d), "client generators, including:", ", ".join(x for x in d if x in ("csharp","go","java","kotlin","python","rust","typescript-axios")))' "${OAG[@]}" -K <(gate) "https://$H/api/gen/servers" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(len(d), "server generators, including:", ", ".join(x for x in d if x in ("aspnetcore","go-server","python-fastapi","spring")))'
89 client generators, including: csharp, go, java, kotlin, python, rust, typescript-axios 73 server generators, including: aspnetcore, go-server, python-fastapi, spring

A client from a published specification. Give the generator a URL. It fetches the specification, generates the client and answers with a download code. The download is a zip, and each code can be downloaded once:

H=$(sudo sed -n 's/^OAG_HOST=//p' /var/lib/sac/data/openapi-generator-credentials.txt) gate() {
sudo awk -F= '/^OAG_AUTH_USER=/{u=$2} /^OAG_AUTH_PASSWORD=/{p=$2} END{printf "user = \"%s:%s\"\n", u, p}' /var/lib/sac/data/openapi-generator-credentials.txt; } OAG=(curl -s --cacert /etc/ssl/openapi-generator/openapi-generator.crt --resolve "$H:443:127.0.0.1") cd "$(mktemp -d)" "${OAG[@]}" -K <(gate) -H 'Content-Type: application/json' \
  -d '{"openAPIUrl":"https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/_archive_/schemas/v3.0/pass/petstore.yaml","options":{"packageName":"petstore_client"}}' \
  "https://$H/api/gen/clients/python" > response.json
CODE=$(python3 -c 'import json; print(json.load(open("response.json"))["code"])') "${OAG[@]}" -K <(gate) -H 'Sec-Fetch-Site: same-origin' -o petstore-python.zip -w '%{http_code} %{content_type}\n' "https://$H/api/gen/download/$CODE" unzip -l petstore-python.zip | awk '{print $4}' | grep -E '^python-client/petstore_client/(api|models)/[a-z_]+\.py$' | sort unzip -p petstore-python.zip python-client/petstore_client/api/pets_api.py | grep -oE 'def (list_pets|create_pets|show_pet_by_id)\(' | sort -u
200 application/zip python-client/petstore_client/api/__init__.py python-client/petstore_client/api/pets_api.py python-client/petstore_client/models/__init__.py python-client/petstore_client/models/error.py python-client/petstore_client/models/pet.py def create_pets( def list_pets( def show_pet_by_id(

The download route only answers requests that come from this server's own pages or from tools that say so. Send Sec-Fetch-Site: same-origin from scripts, as above. Browsers send it automatically from the console.

A server stub from your own specification. Send the specification in the request body instead ({"spec": ...}). This example generates a Go server:

H=$(sudo sed -n 's/^OAG_HOST=//p' /var/lib/sac/data/openapi-generator-credentials.txt) gate() {
sudo awk -F= '/^OAG_AUTH_USER=/{u=$2} /^OAG_AUTH_PASSWORD=/{p=$2} END{printf "user = \"%s:%s\"\n", u, p}' /var/lib/sac/data/openapi-generator-credentials.txt; } OAG=(curl -s --cacert /etc/ssl/openapi-generator/openapi-generator.crt --resolve "$H:443:127.0.0.1") cd "$(mktemp -d)" cat > task.json <<'JSON' { "openapi": "3.0.3", "info": { "title": "Task API", "version": "1.0.0" }, "paths": { "/tasks": { "get": { "operationId": "listTasks", "tags": ["tasks"], "responses": { "200": { "description": "ok", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Task" } } } } } } } } }, "components": { "schemas": { "Task": { "type": "object", "required": ["id", "title"], "properties": { "id": { "type": "integer" }, "title": { "type": "string" }, "done": { "type": "boolean" } } } } } } JSON python3 -c 'import json; print(json.dumps({"spec": json.load(open("task.json"))}))' > body.json
CODE=$("${OAG[@]}" -K <(gate) -H 'Content-Type: application/json' -d @body.json "https://$H/api/gen/servers/go-server" | python3 -c 'import json,sys; print(json.load(sys.stdin)["code"])') "${OAG[@]}" -K <(gate) -H 'Sec-Fetch-Site: same-origin' -o task-go-server.zip -w '%{http_code}\n' "https://$H/api/gen/download/$CODE" unzip -l task-go-server.zip | awk '{print $4}' | grep -E '^go-server-server/(main\.go|go/(api_tasks(_service)?|model_task)\.go)$' | sort
200 go-server-server/go/api_tasks.go go-server-server/go/api_tasks_service.go go-server-server/go/model_task.go go-server-server/main.go

Every generator option the console lists for a language (GET /api/gen/clients/{language}) can be passed in options.

7

What the front door refuses

Without the password, every path answers 401. With the password, the gate still refuses three things. Another web site cannot post to the generator or trigger a download in your browser. A specification URL that points back into the instance is rejected. Plain HTTP only redirects.

Run these checks to see each refusal:

H=$(sudo sed -n 's/^OAG_HOST=//p' /var/lib/sac/data/openapi-generator-credentials.txt) gate() {
sudo awk -F= '/^OAG_AUTH_USER=/{u=$2} /^OAG_AUTH_PASSWORD=/{p=$2} END{printf "user = \"%s:%s\"\n", u, p}' /var/lib/sac/data/openapi-generator-credentials.txt; } OAG=(curl -s --cacert /etc/ssl/openapi-generator/openapi-generator.crt --resolve "$H:443:127.0.0.1") "${OAG[@]}" -o /dev/null -w 'no password: %{http_code}\n' "https://$H/api/gen/clients" "${OAG[@]}" -K <(gate) -o /dev/null -w 'cross-site POST: %{http_code}\n' -X POST -H 'Origin: https://evil.example' -H 'Content-Type: application/json' -d '{}' "https://$H/api/gen/clients/go" "${OAG[@]}" -K <(gate) -o /dev/null -w 'cross-site download: %{http_code}\n' -H 'Sec-Fetch-Site: cross-site' "https://$H/api/gen/download/00000000-0000-0000-0000-000000000000" "${OAG[@]}" -K <(gate) -o /dev/null -w 'spec URL on loopback: %{http_code}\n' -H 'Content-Type: application/json' -d '{"openAPIUrl":"http://127.0.0.1:8080/api-docs"}' "https://$H/api/gen/clients/go" curl -s -o /dev/null -w 'plain http: %{http_code}\n' --resolve "$H:80:127.0.0.1" "http://$H/"
no password: 401 cross-site POST: 403 cross-site download: 403 spec URL on loopback: 400 plain http: 301

A separate script checks the spec-fetch fence. It also proves that the check is real: the same request without the fence succeeds.

sudo /usr/local/sbin/openapi-generator-egress-check.sh
the service unit denies the metadata service (IPv4 and fd00:ec2::254) and every RFC1918 range, and allows loopback inside that filter, as oagen: IMDSv2 token PUT 000, loopback 127.0.0.1:8080 and [::1] 000, a public host 200, DNS resolves control: as root without the filter, the same loopback request answers 200 control: without the filter the IMDSv2 token PUT answers 200 — so the 000 above is the filter, not the network OAG_EGRESS_OK

A specification URL on a private address in your VPC is refused the same way. If the generator needs to fetch specifications from an internal host, host them on a public URL or paste them into the request body instead.

8

Run the self-test

The image ships a self-test. It checks the listening ports, every refusal of the password gate, a full Python client generation and download (with checks on the archive's contents), the spec-fetch fence, and the self-test's own checks against known-bad inputs. It cleans up after itself, so you can run it at any time:

sudo /usr/local/sbin/openapi-generator-selftest.sh | grep -E '_OK$'
[ports] OAG_PORTS_OK [auth] OAG_AUTH_OK [generate] OAG_ROUNDTRIP_OK [egress] OAG_EGRESS_OK [gates] OAG_GATES_OK OAG_SELFTEST_OK
9

Use your own domain name

Point a DNS record at the instance, then set the name with the helper. It generates a new certificate for the name, pins nginx to it (other host names are refused) and writes it into every download link the generator returns:

sudo /usr/local/sbin/openapi-generator-set-hostname <your-domain>

To use a CA-issued certificate, replace /etc/ssl/openapi-generator/openapi-generator.crt and .key with your own. Keep the key root-only, with mode 0600. Then run sudo systemctl reload nginx.

10

Change the password

The helper reads the new password from standard input, so it never appears in your shell history or the process list. It refuses short, all-digit and well-known passwords. It then proves that the new password works and the old one is refused:

# type your <new-password> at the prompt read -rs -p 'New password: ' NEWPW && printf '%s' "$NEWPW" | sudo /usr/local/sbin/openapi-generator-set-password.sh; unset NEWPW
11

Security notes

The certificate generated at first boot is a server certificate only. It cannot sign other certificates. Confirm this with openssl:

openssl x509 -in /etc/ssl/openapi-generator/openapi-generator.crt -noout -ext basicConstraints,keyUsage,extendedKeyUsage
X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication

Known advisories with no fix on this release line. OpenAPI Generator Online 7.26.0 is built on Spring Framework 5.3 and Spring Boot 2.5, whose open-source support has ended. The image moves every library to the newest release on its line, which clears most advisories.

Ten advisories have no fix on these lines. Each needs a feature this image does not use (Spring's HTTP invoker, XSLT views, functional routes, Spring Security, actuator endpoints, persistent sessions, server-side views or expression parsing of user input). For static file handling, the feature is switched off because nginx serves the console files. The build checks each condition and fails if one changes. The list, with the reason for each, is in /usr/share/doc/sac-openapi-generator/RESIDUALS:

grep -oE '^CVE-[0-9]{4}-[0-9]+(/[0-9]+)?' /usr/share/doc/sac-openapi-generator/RESIDUALS
CVE-2016-1000027 CVE-2026-47884 CVE-2024-38816/38819 CVE-2026-41842 CVE-2026-41845 CVE-2026-41849/41850 CVE-2025-41249 CVE-2025-22235 CVE-2026-40973 CVE-2026-55760

The console is the RapiDoc page bundled with the jar. It does not include DOMPurify, and it includes older copies of lodash and marked. The image therefore limits the console to rendering this server's own API description and serves it with a Content-Security-Policy that allows only this server's scripts.

Generated code is yours. OpenAPI Generator is Apache-2.0 licensed, and the project states that generated code is not covered by its licence.

12

Keep it up to date

Ubuntu security updates install automatically. To apply everything now:

sudo apt-get update && sudo apt-get -y upgrade

New OpenAPI Generator releases arrive as new versions of the AWS Marketplace listing. Launch the new version and move your pipelines to it.

Support

SecureAnyCloud images come with 24/7 support. Contact us by email or through the website:

  • Email: sales@secureanycloud.com
  • Website: https://secureanycloud.com

The other versions on this listing are covered in the developer and API tools guide.

Deploy on AWS

Launch OpenAPI Generator 7.26.0 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS