Skip to content

Setup & first user

What happens

The first time APIM starts, it fills in the rows everything else depends on: the admin user and roles, the built-in Key Manager, the default rate-limit tiers, the built-in operation policies, the LLM providers and the default governance rules. Later, the first time a user does something in the Developer Portal, APIM creates a subscriber row for them and a DefaultApplication.

Who: APIM server at startup, then each user on first Dev Portal action · Tables written: UM_USER, UM_ROLE, UM_HYBRID_ROLE, AM_KEY_MANAGER, AM_POLICY_*, AM_API_THROTTLE_POLICY, AM_OPERATION_POLICY, AM_LLM_PROVIDER, GOV_*, AM_GW_INSTANCES, AM_SYSTEM_CONFIGS, AM_SUBSCRIBER, AM_APPLICATION · Tables read: UM_USER_ROLE

The flow at a glance

This diagram shows the two moments that create "starter" data: server startup, and a user's first action in the Developer Portal.

sequenceDiagram
    participant Server as APIM server
    participant DB as Database
    actor User as Developer
    participant Portal as Dev Portal
    Server->>DB: Create admin user and roles (UM_*)
    Server->>DB: Add Resident Key Manager (AM_KEY_MANAGER)
    Server->>DB: Add default tiers (AM_POLICY_*)
    Server->>DB: Add operation policies, LLM providers, governance rules
    User->>Portal: First action (e.g. create an app)
    Portal->>DB: insert AM_SUBSCRIBER + DefaultApplication
  • The first four messages happen once, the first time the server starts against an empty database.
  • The last message happens once per user, the first time they do anything in the Developer Portal.

Step by step

Starter data comes from code, not SQL

The 4.7.0 database scripts only insert a handful of lookup rows, such as the 7 AM_ALERT_TYPES. Everything below is created by the server at startup.

  1. Admin user and roles. The shared DB's user store tables are populated.

    • The super tenant carbon.super has the fixed tenant ID -1234 and no row in UM_TENANT. Only extra tenants get a row there.
    • UM_USER gets two users: admin, and an internal apim_reserved_user. UM_ROLE gets admin, and UM_HYBRID_ROLE gets the internal roles: everyone, system, publisher, creator, subscriber, devops, observer, integration_dev and analytics.
    • UM_PERMISSION and UM_ROLE_PERMISSION get the permission tree, and the registry (REG_*) gets its base folders (around 500 resources).
    UM_USER.UM_USER_NAME UM_TENANT_ID
    admin -1234
    apim_reserved_user -1234
  2. Resident Key Manager. One row goes into AM_KEY_MANAGER: NAME = 'Resident Key Manager', TYPE = 'default', ORGANIZATION = 'carbon.super', and a generated UUID such as b446…. Its settings (token endpoint, grant types and so on) live in the CONFIGURATION blob. Other tables refer to this Key Manager by its UUID.

  3. Default tiers. The default rate-limit policies are inserted:

    • 18 subscription tiers into AM_POLICY_SUBSCRIPTION: Gold, Silver, Bronze, Unauthenticated, DefaultSubscriptionless and Unlimited, plus the Async* and AsyncWH* event tiers and the AIGold / AISilver / AIBronze token tiers;
    • 50PerMin, 20PerMin, 10PerMin and Unlimited into AM_POLICY_APPLICATION;
    • 50KPerMin, 20KPerMin, 10KPerMin and Unlimited into AM_API_THROTTLE_POLICY.

    All of them are keyed by (NAME, TENANT_ID). No custom (global) policy is created.

  4. Other built-in content.

    Not seeded

    AM_GATEWAY_ENVIRONMENT stays empty. The Default environment comes from deployment.toml, not from the database. AM_SYSTEM_APPS also stays empty until someone logs into a portal UI, which registers that portal's own OAuth client there.

  5. First Dev Portal action → subscriber. The first time a user calls the Dev Portal (in the test, by creating an application), APIM inserts a row into AM_SUBSCRIBER, unique on (TENANT_ID, USER_ID). In the same moment it creates the user's DefaultApplication in AM_APPLICATION. See Create an application.

    SUBSCRIBER_ID USER_ID TENANT_ID EMAIL_ADDRESS
    1 admin -1234 (empty)

Logical link (no foreign key)

AM_SUBSCRIBER.USER_ID holds a username, not a foreign key. It matches UM_USER.UM_USER_NAME when you use the JDBC user store, but if users live in LDAP or Active Directory there's no user row in the database at all. TENANT_ID columns across APIM hold the tenant ID by value only (-1234 = super tenant, which has no UM_TENANT row).

  1. Organizations (optional). If you enable organizations, AM_ORGANIZATION_MAPPING maps an APIM organization (ORG_UUID) to an external one (EXT_ORG_ID, PARENT_ORG_UUID). Most 4.x tables have an ORGANIZATION column. By default it holds the tenant domain (carbon.super).

What gets cleaned up

This data is almost never deleted. - Deleting an AM_SUBSCRIBER row is blocked (ON DELETE RESTRICT) while the subscriber still owns applications. - Disabling a tenant sets UM_TENANT.UM_ACTIVE = false rather than deleting the row.

Try it

This query lists the Key Managers, the default subscription tiers and the subscribers for the super tenant.

SELECT NAME, TYPE, ENABLED, ORGANIZATION FROM AM_KEY_MANAGER;

SELECT NAME, QUOTA_TYPE, QUOTA, UNIT_TIME, TIME_UNIT FROM AM_POLICY_SUBSCRIPTION WHERE TENANT_ID = -1234;

SELECT SUBSCRIBER_ID, USER_ID, TENANT_ID, DATE_SUBSCRIBED FROM AM_SUBSCRIBER;

Different in 3.x

3.x bootstraps the same way. The main difference is that tables are scoped by TENANT_ID rather than an ORGANIZATION column, and there are no LLM providers, operation policies or governance rules. See 3.x: Setup & first user.

Related domains: Tenants & users · Keys & tokens · Throttling policies