@postman-cse/onboarding-azure-spec-discovery 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Postman, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,164 @@
1
+ # Postman Onboarding: Azure Spec Discovery
2
+
3
+ [![CI](https://github.com/postman-cs/postman-azure-spec-discovery-action/actions/workflows/ci.yml/badge.svg)](https://github.com/postman-cs/postman-azure-spec-discovery-action/actions/workflows/ci.yml) [![Release](https://img.shields.io/github/v/release/postman-cs/postman-azure-spec-discovery-action?sort=semver)](https://github.com/postman-cs/postman-azure-spec-discovery-action/releases) [![npm](https://img.shields.io/npm/v/%40postman-cse%2Fonboarding-azure-spec-discovery)](https://www.npmjs.com/package/@postman-cse/onboarding-azure-spec-discovery) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
+
5
+ Zero-config discovery and export of API specs from Azure services using only your existing Azure credentials. Use it when a service already runs on Azure and you need a source-of-truth [Spec Hub](https://learning.postman.com/docs/design-apis/specifications/overview/) specification that Postman onboarding can turn into deterministic collections, OpenAPI-backed contract checks, smoke tests, mocks, monitors, repo artifacts, and CI runs.
6
+
7
+ The action resolves the best specification source for the current repository in this order:
8
+
9
+ 1. **Repo spec** — an OpenAPI/Swagger file already committed to the repository wins outright; Azure is never called.
10
+ 2. **Azure API Management (APIM)** — the current HTTP revision of an APIM API, exported as OpenAPI 3.0 JSON through the ARM export protocol.
11
+ 3. **App Service API definition** — a site whose `apiDefinition.url` points at a reachable OpenAPI document.
12
+ 4. **Local Azure IaC** — OpenAPI content embedded in ARM/Bicep templates or referenced by `azure.yaml` in the repository.
13
+
14
+ When several Azure candidates match, a four-tier narrowing pipeline (IaC fingerprint, resource-group correlation, `postman:*` tag prefilter, naming heuristic) orders them, and genuinely ambiguous results surface as a ranked GitHub Step Summary table instead of a guess.
15
+
16
+ ## Auth and Postman handoff
17
+
18
+ The action authenticates with `DefaultAzureCredential` — GitHub OIDC via `azure/login`, environment credentials, or Azure CLI login all work with no extra configuration. It needs only read access (`Reader` plus `API Management Service Reader` covers everything). It never creates, modifies, or deletes Azure resources.
19
+
20
+ The optional `postman-api-key` / `postman-access-token` inputs exist only to enrich anonymous telemetry with the session account type. They are never used for Azure calls or Postman asset operations.
21
+
22
+ ## Usage
23
+
24
+ ```yaml
25
+ jobs:
26
+ discover:
27
+ runs-on: ubuntu-latest
28
+ permissions:
29
+ id-token: write
30
+ contents: read
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+ - uses: azure/login@v2
34
+ with:
35
+ client-id: ${{ secrets.AZURE_CLIENT_ID }}
36
+ tenant-id: ${{ secrets.AZURE_TENANT_ID }}
37
+ subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
38
+ - id: spec
39
+ uses: postman-cs/postman-azure-spec-discovery-action@v1
40
+ - run: echo "Resolved ${{ steps.spec.outputs.source-type }} -> ${{ steps.spec.outputs.spec-path }}"
41
+ ```
42
+
43
+ ## Examples
44
+
45
+ ### Zero-config resolve-one
46
+
47
+ ```yaml
48
+ - uses: postman-cs/postman-azure-spec-discovery-action@v1
49
+ ```
50
+
51
+ ### Known APIM API
52
+
53
+ ```yaml
54
+ - uses: postman-cs/postman-azure-spec-discovery-action@v1
55
+ with:
56
+ api-id: /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.ApiManagement/service/<svc>/apis/<api>
57
+ ```
58
+
59
+ ### discover-many mode
60
+
61
+ ```yaml
62
+ - uses: postman-cs/postman-azure-spec-discovery-action@v1
63
+ with:
64
+ mode: discover-many
65
+ resource-group: payments-rg
66
+ ```
67
+
68
+ ### Chaining into Postman API onboarding
69
+
70
+ ```yaml
71
+ - id: spec
72
+ uses: postman-cs/postman-azure-spec-discovery-action@v1
73
+ - uses: postman-cs/postman-api-onboarding-action@v1
74
+ with:
75
+ postman-api-key: ${{ secrets.POSTMAN_API_KEY }}
76
+ spec-path: ${{ steps.spec.outputs.spec-path }}
77
+ ```
78
+
79
+ ### GitLab and other CI (portable CLI)
80
+
81
+ ```sh
82
+ npx @postman-cse/onboarding-azure-spec-discovery \
83
+ --subscription-id "$AZURE_SUBSCRIPTION_ID" \
84
+ --result-json postman-azure-spec-discovery-result.json \
85
+ --dotenv-path azure-spec.env
86
+ ```
87
+
88
+ The CLI exposes every action input as a `--kebab-case` flag plus CLI-only flags for repo context and discovery tuning (`--repo-root`, `--expected-service-name`, `--dry-run`, `--max-candidates`, and friends). `--help` lists all of them.
89
+
90
+ ## Inputs
91
+
92
+ <!-- inputs-table:start -->
93
+ | Name | Description | Required | Default |
94
+ | --- | --- | --- | --- |
95
+ | `mode` | Discovery mode: resolve-one selects the single best service for this repository; discover-many exports every exportable candidate. | no | `resolve-one` |
96
+ | `subscription-id` | Optional Azure subscription ID used as the discovery enumeration root. When omitted, the single enabled subscription visible to the credential is used; multiple enabled subscriptions require this input. | no | n/a |
97
+ | `resource-group` | Optional resource group that scopes discovery to one group instead of the whole subscription. | no | n/a |
98
+ | `api-id` | Optional full APIM API ARM resource ID for this service. Use this to bypass broader subscription discovery. | no | n/a |
99
+ | `output-dir` | Directory under the repository root where generated specs are written. | no | `discovered-specs` |
100
+ | `postman-api-key` | Optional service-account PMAK used to mint or re-mint a postman-access-token for telemetry enrichment (account_type). Not used for any Azure or Postman asset operation. | no | n/a |
101
+ | `postman-access-token` | Optional Postman service-account access token, used only to enrich anonymous telemetry with the session account_type. When omitted, postman-api-key alone can mint one for the same purpose. Not used for any Azure or Postman asset operation. | no | n/a |
102
+ <!-- inputs-table:end -->
103
+
104
+ ## Outputs
105
+
106
+ <!-- outputs-table:start -->
107
+ | Name | Description |
108
+ | --- | --- |
109
+ | `resolution-json` | JSON resolution result describing status, source type, confidence, and evidence. |
110
+ | `resolution-status` | Resolution status: resolved or unresolved. |
111
+ | `source-type` | Resolved source type: repo-spec, apim-export, app-service-api-definition, iac-embedded, manual-review, or discover-many. |
112
+ | `mapping-confidence` | Numeric confidence score for the selected service candidate. |
113
+ | `spec-path` | Path to the resolved or generated specification when available. |
114
+ | `api-id` | Full APIM API ARM resource ID for APIM resolutions; empty for App Service or IaC-local resolutions. |
115
+ | `service-name` | Resolved service name. |
116
+ | `services-json` | discover-many output: JSON array of exported services. |
117
+ | `service-count` | discover-many output: number of exported services. |
118
+ | `export-summary-json` | JSON summary of attempted, exported, failed, and skipped candidates. |
119
+ | `candidates-json` | Ranked ambiguous candidates as JSON when resolution is unresolved with at least two candidates; empty otherwise. |
120
+ | `provider-type` | Provider that produced the resolved spec: apim, app-service, or iac-local. |
121
+ | `spec-format` | Format of the resolved spec: openapi-yaml or openapi-json. |
122
+ | `contract-origin` | Compatibility output; always empty in v1. |
123
+ | `contract-metadata-path` | Compatibility output; always empty in v1. |
124
+ | `variant-count` | Compatibility output; always empty in v1. |
125
+ | `derived-openapi-path` | Path to the derived OpenAPI 3.x document when the source was not already OpenAPI 3.x. |
126
+ | `derived-openapi-version` | OpenAPI version of the derived document: 3.0.3 or 3.1.0. |
127
+ | `derived-openapi-completeness` | Whether the derived OpenAPI document is full or partial. |
128
+ | `derived-openapi-format` | Serialization format of the derived OpenAPI document: openapi-json. |
129
+ | `derived-openapi-evidence-json` | JSON array of evidence strings describing how the derived OpenAPI document was produced. |
130
+ | `narrowing-strategy` | Narrowing tier that produced the candidate ordering: iac-fingerprint, rg-correlation, tag-prefilter, naming-heuristic, or none. |
131
+ <!-- outputs-table:end -->
132
+
133
+ ## Supported providers
134
+
135
+ | Provider | Source | Exported format |
136
+ | --- | --- | --- |
137
+ | `apim` | Azure API Management current HTTP API revision (ARM export + SAS link) | OpenAPI 3.0 JSON |
138
+ | `app-service` | App Service `siteConfig.apiDefinition.url` document | OpenAPI JSON or YAML |
139
+ | `iac-local` | OpenAPI embedded in repo ARM/Bicep templates or referenced by `azure.yaml` | OpenAPI JSON or YAML |
140
+
141
+ Non-HTTP APIM API types (SOAP, GraphQL, WebSocket, gRPC, OData) are surfaced as visible-unsupported candidates and routed to manual review; they are never exported in v1. Service- and workspace-scoped APIM APIs are both enumerated. Azure API Center, Functions, Container Apps, and management-group enumeration are out of scope for v1.
142
+
143
+ ## How it works
144
+
145
+ 1. Resolve inputs, repository context, and the target subscription (explicit `subscription-id`, or the single enabled subscription).
146
+ 2. Short-circuit to a committed repo spec when one exists.
147
+ 3. Probe providers fail-soft: an unauthorized provider is skipped (`skipped:iam`), an erroring one is skipped (`skipped:error`), and discovery continues with the rest.
148
+ 4. Enumerate candidates, narrow with the four-tier pipeline, and score against repository signals.
149
+ 5. Export the winner (APIM ARM export, guarded HTTPS fetch, or IaC extraction), validate it is real OpenAPI/Swagger with at least one path, and write it under `output-dir` confined to the repository root.
150
+ 6. Emit all 22 outputs; ambiguous resolutions additionally render a ranked Step Summary table.
151
+
152
+ ## Resources
153
+
154
+ - [docs/providers.md](docs/providers.md) — provider contracts and evidence semantics.
155
+ - [docs/LIVE_TESTING_RUNBOOK.md](docs/LIVE_TESTING_RUNBOOK.md) — operator-run live Azure validation.
156
+ - [RELEASE_POLICY.md](RELEASE_POLICY.md), [SECURITY.md](SECURITY.md), [SUPPORT.md](SUPPORT.md).
157
+
158
+ ## Telemetry
159
+
160
+ The action emits one anonymous `completion` event per run (action name `azure-spec-discovery`) through `@postman-cse/automation-telemetry-core`. The payload never contains Azure subscription, tenant, or resource identifiers, resource names, tags, spec content, URLs, or credentials. Opt out with `POSTMAN_ACTIONS_TELEMETRY=off` or `DO_NOT_TRACK=1`.
161
+
162
+ ## License
163
+
164
+ [MIT](LICENSE)
@@ -0,0 +1,43 @@
1
+ # Release Policy
2
+
3
+ ## Source of truth
4
+
5
+ Git tags and GitHub releases are the public release identifiers for this action. `package.json` versions support npm packaging, but consumers should select action versions by Git tag. The committed `dist/` bundle is part of the released artifact because GitHub Actions runs it verbatim from the tag.
6
+
7
+ ## Tag policy
8
+
9
+ - Immutable releases use `vMAJOR.MINOR.PATCH` tags.
10
+ - The rolling major and minor aliases (`vMAJOR` and `vMAJOR.MINOR`, i.e. `v1` and `v1.0`) are force-moved by the release workflow's `advance-rolling-aliases` job after a successful immutable publish.
11
+ - Existing immutable release tags are never force-pushed or rewritten.
12
+ - Every release tag commit must equal protected `origin/main`; the release workflow verifies this before publication.
13
+ - `v0` tags stay frozen at the last `v0` release.
14
+ - Every immutable release tag has a GitHub release with generated notes.
15
+
16
+ ## Release checks
17
+
18
+ Run the package validators from this directory before pushing an immutable tag:
19
+
20
+ 1. Confirm the working tree is clean.
21
+ 2. `npm test`
22
+ 3. `npm run typecheck`
23
+ 4. `npm run lint`
24
+ 5. `npm run build`
25
+ 6. `npm run verify:dist`
26
+ 7. `npm run docs:tables` when `action.yml` changes, then confirm the `README.md` tables still match.
27
+ 8. Confirm `SECURITY.md`, `SUPPORT.md`, and this file still describe the release surface.
28
+
29
+ ## npm package
30
+
31
+ The CLI publishes as `@postman-cse/onboarding-azure-spec-discovery` with versions that match the GitHub release tag. Rolling major/minor aliases update action channels and skip npm publishing.
32
+
33
+ ## Compatibility
34
+
35
+ This action emits `spec-path`, `service-name`, and resolution metadata for downstream actions. Changes to output names, output types, required inputs, or resolution semantics are breaking changes and require a new major release.
36
+
37
+ ## Security fixes
38
+
39
+ Security fixes ship on the latest immutable `vMAJOR.MINOR.PATCH` tag and move onto the rolling major/minor aliases. Older immutable tags stay published for reproducibility. See [Security Policy](SECURITY.md).
40
+
41
+ ## Suite release order
42
+
43
+ Azure discovery can be released on its own unless a downstream onboarding example depends on a new composite or bootstrap feature. When multiple onboarding actions change together, release the lower-level actions first, then update the composite action after its pinned dependencies are available.
package/SECURITY.md ADDED
@@ -0,0 +1,32 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ Only the latest `v1.x.y` release (tracked by rolling major and minor aliases such as `v1` and `v1.0`) receives security fixes. Older tags remain published for reproducibility and are never retroactively modified.
6
+
7
+ ## Reporting a Vulnerability
8
+
9
+ Please do not open a public issue for security reports.
10
+
11
+ - Preferred: use GitHub private vulnerability reporting on this repository (Security tab, "Report a vulnerability").
12
+ - Alternative: email [security@postman.com](mailto:security@postman.com) and mention the repository name.
13
+
14
+ You should receive an acknowledgement within five business days. Please include reproduction steps, the action version tag, and any relevant (redacted) workflow logs.
15
+
16
+ ## Scope Notes
17
+
18
+ - This action reads Azure credentials from the runner environment and calls read-only Azure ARM APIs. Prefer GitHub OIDC federation via `azure/login` with `id-token: write` and least-privilege Reader roles needed for the providers you use.
19
+ - This action does not require a Postman API key or Postman access token. Postman credentials are consumed by downstream onboarding actions after `spec-path` is resolved.
20
+ - Use `postman-resolve-service-token-action` as the primary way to mint a Postman access token and resolve the team ID from a service-account PMAK.
21
+ - When service-account minting is unavailable, use the Postman CLI credential store created by `postman login` as the fallback source. Do not paste copied cookies, DevTools values, or manually harvested session credentials into workflow secrets.
22
+ - Downstream `credential-preflight` supports `warn` and `enforce` only. Do not document or depend on a public opt-out.
23
+ - Reports about secrets you exposed in your own workflow configuration are out of scope; rotate the credential in Azure or Postman immediately.
24
+
25
+ ## Credential Matrix
26
+
27
+ | Credential | Used by | Recommended source | Notes |
28
+ | --- | --- | --- | --- |
29
+ | Azure credentials | `azure/login` and this action | GitHub OIDC federated credentials | Grant least-privilege Reader roles for discovery. |
30
+ | `POSTMAN_SERVICE_ACCOUNT_API_KEY` | `postman-resolve-service-token-action` and downstream onboarding actions | GitHub secret | Must be a Postman service-account PMAK when minting an access token. |
31
+ | Postman access token | Downstream onboarding actions | `postman-resolve-service-token-action` output | Pass through `steps.postman_token.outputs.token`; do not store unless your workflow requires it. |
32
+ | Postman team ID | Composite onboarding action | `postman-resolve-service-token-action` output | Pass through `steps.postman_token.outputs.team-id` to the composite action for org-mode handoff. Direct bootstrap workflows should use `workspace-team-id` for workspace creation. |
package/SUPPORT.md ADDED
@@ -0,0 +1,30 @@
1
+ # Support
2
+
3
+ ## Before opening an issue
4
+
5
+ Check the action logs for the selected provider, `resolution-status`, `source-type`, and `mapping-confidence`. The action is read-only against Azure and silently skips providers your role cannot read, so most discovery failures are caused by subscription mismatch, missing RBAC read permissions, missing repo-local specs, or ambiguous service names.
6
+
7
+ ## What to include
8
+
9
+ - The action version or tag you ran.
10
+ - The `subscription-id` value and provider you expected to resolve.
11
+ - The relevant sanitized workflow step log.
12
+ - The `resolution-json` output with secrets, subscription IDs, and private hostnames redacted.
13
+ - Whether the workflow used azure/login OIDC federation or preconfigured Azure credentials.
14
+ - Whether the result was handed to `postman-api-onboarding-action` or `postman-bootstrap-action`.
15
+
16
+ Do not include Azure secrets, Postman API keys, Postman access tokens, private OpenAPI documents, or unredacted account identifiers in public issues.
17
+
18
+ ## Common support paths
19
+
20
+ | Symptom | First check |
21
+ | --- | --- |
22
+ | `Azure credentials are missing or invalid` | Confirm `azure/login` ran first and the federated credential covers this repository and environment. |
23
+ | Provider was skipped | Add the provider's read-only IAM permissions from [docs/providers.md](docs/providers.md#security-and-iam). |
24
+ | `manual-review` result | Provide a repo-local spec, an exact APIM `api-id`, a canonical `postman:repo` tag, or a stronger service-name hint. |
25
+ | Downstream Postman onboarding failed | Check the service-token step outputs and downstream `credential-preflight` setting. Valid values are `warn` and `enforce`. |
26
+ | APIM or App Service API was not selected | Confirm the resource group, API type, current APIM revision, and `siteConfig.apiDefinition.url`; then review [docs/providers.md](docs/providers.md). |
27
+
28
+ ## Security reports
29
+
30
+ Use [SECURITY.md](SECURITY.md) for vulnerability reports or credential exposure concerns. Do not open a public issue for security-sensitive material.
package/action.yml ADDED
@@ -0,0 +1,83 @@
1
+ name: 'Postman Onboarding: Azure Spec Discovery'
2
+ description: Discover Azure-hosted API specs and expose a spec path for Postman onboarding. Part of the Postman API Onboarding suite.
3
+ author: Postman
4
+ branding:
5
+ icon: cloud
6
+ color: orange
7
+ inputs:
8
+ mode:
9
+ description: 'Discovery mode: resolve-one selects the single best service for this repository; discover-many exports every exportable candidate.'
10
+ required: false
11
+ default: resolve-one
12
+ subscription-id:
13
+ description: Optional Azure subscription ID used as the discovery enumeration root. When omitted, the single enabled subscription visible to the credential is used; multiple enabled subscriptions require this input.
14
+ required: false
15
+ default: ''
16
+ resource-group:
17
+ description: Optional resource group that scopes discovery to one group instead of the whole subscription.
18
+ required: false
19
+ default: ''
20
+ api-id:
21
+ description: Optional full APIM API ARM resource ID for this service. Use this to bypass broader subscription discovery.
22
+ required: false
23
+ default: ''
24
+ output-dir:
25
+ description: Directory under the repository root where generated specs are written.
26
+ required: false
27
+ default: discovered-specs
28
+ postman-api-key:
29
+ description: Optional service-account PMAK used to mint or re-mint a postman-access-token for telemetry enrichment (account_type). Not used for any Azure or Postman asset operation.
30
+ required: false
31
+ default: ''
32
+ postman-access-token:
33
+ description: Optional Postman service-account access token, used only to enrich anonymous telemetry with the session account_type. When omitted, postman-api-key alone can mint one for the same purpose. Not used for any Azure or Postman asset operation.
34
+ required: false
35
+ default: ''
36
+ outputs:
37
+ resolution-json:
38
+ description: JSON resolution result describing status, source type, confidence, and evidence.
39
+ resolution-status:
40
+ description: 'Resolution status: resolved or unresolved.'
41
+ source-type:
42
+ description: 'Resolved source type: repo-spec, apim-export, app-service-api-definition, iac-embedded, manual-review, or discover-many.'
43
+ mapping-confidence:
44
+ description: Numeric confidence score for the selected service candidate.
45
+ spec-path:
46
+ description: Path to the resolved or generated specification when available.
47
+ api-id:
48
+ description: Full APIM API ARM resource ID for APIM resolutions; empty for App Service or IaC-local resolutions.
49
+ service-name:
50
+ description: Resolved service name.
51
+ services-json:
52
+ description: 'discover-many output: JSON array of exported services.'
53
+ service-count:
54
+ description: 'discover-many output: number of exported services.'
55
+ export-summary-json:
56
+ description: JSON summary of attempted, exported, failed, and skipped candidates.
57
+ candidates-json:
58
+ description: Ranked ambiguous candidates as JSON when resolution is unresolved with at least two candidates; empty otherwise.
59
+ provider-type:
60
+ description: 'Provider that produced the resolved spec: apim, app-service, or iac-local.'
61
+ spec-format:
62
+ description: 'Format of the resolved spec: openapi-yaml or openapi-json.'
63
+ contract-origin:
64
+ description: Compatibility output; always empty in v1.
65
+ contract-metadata-path:
66
+ description: Compatibility output; always empty in v1.
67
+ variant-count:
68
+ description: Compatibility output; always empty in v1.
69
+ derived-openapi-path:
70
+ description: Path to the derived OpenAPI 3.x document when the source was not already OpenAPI 3.x.
71
+ derived-openapi-version:
72
+ description: 'OpenAPI version of the derived document: 3.0.3 or 3.1.0.'
73
+ derived-openapi-completeness:
74
+ description: Whether the derived OpenAPI document is full or partial.
75
+ derived-openapi-format:
76
+ description: 'Serialization format of the derived OpenAPI document: openapi-json.'
77
+ derived-openapi-evidence-json:
78
+ description: JSON array of evidence strings describing how the derived OpenAPI document was produced.
79
+ narrowing-strategy:
80
+ description: 'Narrowing tier that produced the candidate ordering: iac-fingerprint, rg-correlation, tag-prefilter, naming-heuristic, or none.'
81
+ runs:
82
+ using: node24
83
+ main: dist/index.cjs