k3nny 0f1a6d865d feat(apim-apps): add external credentials support for new applications
Applications can now declare a `credentials:` list in the YAML manifest.
Each entry holds a static `client_id` (and optional `secret`) that is
provisioned via POST /applications/{id}/extcredentials when the application
is first created. Existing applications are never modified.

Also adds CHANGELOG.md and ROADMAP.md for the v0.1.0 initial release.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 22:16:48 +02:00
2026-06-29 14:22:37 +02:00
2026-06-29 14:22:37 +02:00
2026-06-29 14:22:37 +02:00
2026-06-29 14:22:37 +02:00
2026-06-29 14:22:37 +02:00
2026-06-29 14:22:37 +02:00
2026-06-29 14:22:37 +02:00
2026-06-29 14:22:37 +02:00

apim-apps

release

CLI tool for managing Axway API Manager client applications from a YAML manifest.
Ensures compliance across multiple environments by creating missing applications, external credentials, and API subscriptions.

How it works

The tool reads a manifest (apps.yaml) describing the desired state, compares it against each Axway API Manager instance, and creates what is missing.

Organisations are managed by hand — the tool looks them up live in the API Manager. If an application references an organisation that does not exist there, the application is skipped and the error is reported clearly.

Credentials are never stored in config files — they are injected via environment variables at runtime.

Requirements

  • Python 3.13+
  • uv
  • Environment variables APIM_USER and APIM_PASSWORD set before running

Setup

uv sync

Generate example files:

uv run python apim_apps.py --init-manifest   # creates apps.yaml
uv run python apim_apps.py --init-config     # creates config.json

Configuration

config.json — environment registry

Lists the Axway API Manager instances. Credentials are not stored here.

{
  "environments": [
    {
      "name": "DEV_LAN",
      "url": "https://apimgr-dev.example.com:8075",
      "verify_ssl": false
    },
    {
      "name": "PROD",
      "url": "https://apimgr-prd.example.com:8075",
      "verify_ssl": true
    }
  ]
}
Field Required Description
name yes Environment identifier used with --env
url yes Base URL of the API Manager instance
verify_ssl no Verify TLS certificate (default: false)

apps.yaml — desired state manifest

Describes the applications that must exist on each environment.
The organizations section is optional — organisations are expected to already exist in the API Manager (managed by hand). If an application's organisation is missing, the application is skipped and the error is reported.

If environments is omitted on an entry, it applies to all environments.

applications:
  - name: "MyApp"
    organization: "MyOrg"        # must already exist in the API Manager
    description: "Mobile application"
    email: "mobile@example.com"
    enabled: true
    environments:
      - DEV_LAN
    credentials:
      - client_id: "my-external-client-id"   # static external credential; optional secret:
    apis:
      - name: "Products"
        version: "v2"
      - "Notifications"           # short form — no version filter

The credentials list is optional. Each entry provisions an external credential (client_id, optional secret) on the application via the API Manager's /extcredentials endpoint. Credentials are set only when the application is first created — existing applications are never modified.

If you also want the tool to manage organisations, add an organizations section:

organizations:
  - name: "MyOrg"
    description: "Partner organisation"
    email: "api@example.com"
    enabled: true
    development: false
    environments:
      - DEV_LAN

applications:
  - name: "MyApp"
    organization: "MyOrg"
    ...

Usage

export APIM_USER=apiadmin
export APIM_PASSWORD=secret

# Dry-run on a single environment
uv run python apim_apps.py --dry-run --env DEV_LAN

# Deploy on a single environment
uv run python apim_apps.py --env DEV_LAN

# Run against all environments in config.json
uv run python apim_apps.py

# Extra options
uv run python apim_apps.py --manifest custom.yaml --config custom.json --verbose

CLI reference

Flag Description
--dry-run Simulate actions, make no changes
--env ENV Target a single environment by name
--manifest FILE Path to YAML manifest (default: apps.yaml)
--config FILE Path to JSON config (default: config.json)
--verbose Log skipped (already-present) resources
--init-manifest Generate a sample apps.yaml and exit
--init-config Generate a sample config.json and exit

GitLab CI/CD integration

Store APIM_USER and APIM_PASSWORD as protected CI/CD variables in your GitLab project settings.

# .gitlab-ci.yml
variables:
  MANIFEST: apps.yaml
  CONFIG: config.json

.apim-base:
  image: ghcr.io/astral-sh/uv:python3.13-alpine
  before_script:
    - uv sync --frozen

dry-run:
  extends: .apim-base
  script:
    - uv run python apim_apps.py --dry-run --env "$APIM_ENV"

deploy:
  extends: .apim-base
  when: manual
  script:
    - uv run python apim_apps.py --env "$APIM_ENV"

Trigger the pipeline with APIM_ENV=DEV_LAN to target a specific environment.

Running tests

uv run pytest
S
Description
No description provided
Readme 68 KiB
Languages
Python 100%