@mcp-abap-adt/auth-broker 3.0.3 → 3.1.0
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/CHANGELOG.md +70 -1
- package/README.md +34 -312
- package/package.json +14 -41
- package/CONTRIBUTORS.md +0 -33
- package/dist/__tests__/helpers/configHelpers.d.ts +0 -59
- package/dist/__tests__/helpers/configHelpers.d.ts.map +0 -1
- package/dist/__tests__/helpers/configHelpers.js +0 -206
- package/dist/__tests__/helpers/netHelpers.d.ts +0 -3
- package/dist/__tests__/helpers/netHelpers.d.ts.map +0 -1
- package/dist/__tests__/helpers/netHelpers.js +0 -63
- package/dist/__tests__/helpers/testLogger.d.ts +0 -7
- package/dist/__tests__/helpers/testLogger.d.ts.map +0 -1
- package/dist/__tests__/helpers/testLogger.js +0 -54
- package/dist/bin/mcp-auth.js +0 -752
- package/dist/bin/mcp-sso.js +0 -825
- package/dist/bin/mcpSsoConfig.js +0 -566
- package/dist/bin/samlMetadata.js +0 -175
- package/dist/bin/workDir.js +0 -79
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,79 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## Contributors
|
|
9
9
|
|
|
10
|
-
Thank you to all contributors! See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the complete list.
|
|
10
|
+
Thank you to all contributors! See [CONTRIBUTORS.md](../../CONTRIBUTORS.md) for the complete list.
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [3.1.0] - 2026-10-01
|
|
15
|
+
|
|
16
|
+
**Why a minor.** The library's API is unchanged: every export, signature and
|
|
17
|
+
behaviour of 3.0.4 stays. What changed is where the commands install from —
|
|
18
|
+
`mcp-auth` and `mcp-sso` are now `@mcp-abap-adt/auth-broker-cli` 1.0.0 — and
|
|
19
|
+
which dependencies this package pulls in. Read the migration below if you
|
|
20
|
+
install this package for its commands, or import `auth-stores` or
|
|
21
|
+
`auth-providers` without declaring them.
|
|
22
|
+
|
|
23
|
+
### Migration
|
|
24
|
+
|
|
25
|
+
- **You run `npm i -g @mcp-abap-adt/auth-broker` for `mcp-auth` / `mcp-sso`:**
|
|
26
|
+
this version has no `bin`. Install the commands from their own package:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm uninstall -g @mcp-abap-adt/auth-broker && npm i -g @mcp-abap-adt/auth-broker-cli
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Commands and flags are the same.
|
|
33
|
+
- **Your code imports `@mcp-abap-adt/auth-stores` or
|
|
34
|
+
`@mcp-abap-adt/auth-providers` and found them only because this package
|
|
35
|
+
depended on them:** declare them in your own `package.json`. This package no
|
|
36
|
+
longer installs either.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- **The repository is a workspace** (the `mcp-abap-adt-interfaces` layout): this
|
|
41
|
+
package is `packages/auth-broker`, and the commands are
|
|
42
|
+
`packages/auth-broker-cli`, published as `@mcp-abap-adt/auth-broker-cli`. Tags
|
|
43
|
+
are `auth-broker-v<version>` from here on; the `v*` tags are this package's
|
|
44
|
+
history up to 3.0.4. Run everything from the repository root: `npm run build`,
|
|
45
|
+
`npm test`, `npm run check`.
|
|
46
|
+
|
|
47
|
+
### Removed
|
|
48
|
+
|
|
49
|
+
- **`bin`: `mcp-auth` and `mcp-sso`** move to `@mcp-abap-adt/auth-broker-cli`,
|
|
50
|
+
commands and flags unchanged (see *Migration*).
|
|
51
|
+
- **`axios`** from the dependencies: nothing imports it.
|
|
52
|
+
- **`@mcp-abap-adt/logger`** from the dependencies: only the commands use it
|
|
53
|
+
at run time; the tests keep it as a dev dependency.
|
|
54
|
+
- **`@mcp-abap-adt/auth-stores` and `@mcp-abap-adt/auth-providers`** from the
|
|
55
|
+
dependencies: the library imports neither, only its tests do (dev
|
|
56
|
+
dependencies now). `tools/check-graph.js` keeps it that way for auth-stores.
|
|
57
|
+
A consumer that imported either without declaring it must declare it (see
|
|
58
|
+
*Migration*).
|
|
59
|
+
- **The test helpers from `dist/`**: `dist/__tests__/helpers` shipped in the
|
|
60
|
+
tarball; the build no longer compiles anything under `src/__tests__`.
|
|
61
|
+
- **`CONTRIBUTORS.md` from the tarball**: it stays at the repository root.
|
|
62
|
+
|
|
63
|
+
## [3.0.4] - 2026-09-28
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
- **`mcp-sso` did not start from an installed package.** It imports
|
|
68
|
+
`@mcp-abap-adt/logger`, which was only a dev dependency, so every command —
|
|
69
|
+
`--version` and `help` included — died with `Cannot find module
|
|
70
|
+
'@mcp-abap-adt/logger'`. It worked in this repository, where dev dependencies
|
|
71
|
+
are installed. `@mcp-abap-adt/logger` is now a runtime dependency. `mcp-auth`
|
|
72
|
+
was not affected. Found by installing the 3.0.3 tarball into an empty
|
|
73
|
+
directory and running each bin.
|
|
74
|
+
|
|
75
|
+
### Tests
|
|
76
|
+
|
|
77
|
+
- **`tests/sso-demo` moves to CAP 10**: `@sap/cds` `^10`, `@sap/cds-dk` `^10`,
|
|
78
|
+
`@cap-js/sqlite` `^3`. `npm audit` there goes from 12 findings (2 critical,
|
|
79
|
+
6 high) to 0: they sat in copies nested under `@sap/cds-dk` 9, which no
|
|
80
|
+
update inside 9.x could reach. `cds build --production` builds the service as
|
|
81
|
+
before. The demo is not part of the published package.
|
|
82
|
+
|
|
14
83
|
## [3.0.3] - 2026-09-27
|
|
15
84
|
|
|
16
85
|
### Added
|
package/README.md
CHANGED
|
@@ -8,8 +8,13 @@ session cookies, with the refresh token. It decides nothing about tokens itself:
|
|
|
8
8
|
cached token is still good, when to refresh and when to log in is the provider's call
|
|
9
9
|
(`@mcp-abap-adt/auth-providers`), and where sessions live is the stores' (`@mcp-abap-adt/auth-stores`).
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
The `mcp-auth` and `mcp-sso` commands that write session files are in
|
|
12
|
+
[`@mcp-abap-adt/auth-broker-cli`](../auth-broker-cli/README.md), in the same
|
|
13
|
+
repository. Up to 3.0.4 they shipped in this package; from 3.1.0 this package
|
|
14
|
+
has no `bin`. Install the commands with
|
|
15
|
+
`npm i -g @mcp-abap-adt/auth-broker-cli` — after
|
|
16
|
+
`npm uninstall -g @mcp-abap-adt/auth-broker` if you had installed this one
|
|
17
|
+
globally for them.
|
|
13
18
|
|
|
14
19
|
## Features
|
|
15
20
|
|
|
@@ -18,7 +23,6 @@ authorization code or client credentials) and `mcp-sso` (OIDC and SAML single si
|
|
|
18
23
|
- ⚡ **Forced refresh**: `refreshToken()` obtains a new token even when the cached one looks valid — for a caller holding a 401
|
|
19
24
|
- 🧾 **JWT or SAML cookies**: what the provider returns is saved as a token or as session cookies
|
|
20
25
|
- 🔑 **No secrets copied**: The client secret stays in the service key; the session store gets tokens only
|
|
21
|
-
- 🧰 **CLIs**: `mcp-auth` and `mcp-sso` produce `.env`/JSON session files, SAML trust read from metadata
|
|
22
26
|
|
|
23
27
|
## Installation
|
|
24
28
|
|
|
@@ -208,7 +212,7 @@ const connection = new JwtAbapConnection(config, tokenRefresher);
|
|
|
208
212
|
it from the service key store if you relied on finding it in the session.
|
|
209
213
|
6. `refreshToken()` now forces a new token; it used to return `getToken()`'s.
|
|
210
214
|
7. Node.js 22, 24 or 26; SAML runs need the IdP trust (see *Migrating `mcp-sso`
|
|
211
|
-
SAML runs from 2.2.0*).
|
|
215
|
+
SAML runs from 2.2.0* in the [CLI's README](../auth-broker-cli/README.md)).
|
|
212
216
|
|
|
213
217
|
## Configuration
|
|
214
218
|
|
|
@@ -602,339 +606,57 @@ const xsuaaBroker = new AuthBroker({
|
|
|
602
606
|
});
|
|
603
607
|
```
|
|
604
608
|
|
|
605
|
-
### CLI: mcp-auth
|
|
606
|
-
|
|
607
|
-
Generate or refresh `.env`/JSON output using AuthBroker + stores:
|
|
608
|
-
|
|
609
|
-
```bash
|
|
610
|
-
mcp-auth <auth-code|oidc|saml2-pure|saml2-bearer> [options]
|
|
611
|
-
mcp-auth --service-key <path> --output <path> [--env <path>] [--type abap|xsuaa] [--credential] [--browser auto|none|system|chrome|edge|firefox] [--format json|env]
|
|
612
|
-
```
|
|
613
|
-
|
|
614
|
-
**Note**: The published CLI is compiled to `dist/bin` and does not require `tsx` at runtime. For repo usage, run `npm install` and `npm run build`.
|
|
615
|
-
|
|
616
|
-
**Authentication Flow:**
|
|
617
|
-
- Default: `authorization_code` (browser-based OAuth2)
|
|
618
|
-
- `--credential`: `client_credentials` (clientId/clientSecret, no browser)
|
|
619
|
-
|
|
620
|
-
**Browser Options (for authorization_code):**
|
|
621
|
-
- `auto` (default): Try to open browser, fallback to showing URL
|
|
622
|
-
- `none`: Show URL in console and wait for callback (no browser)
|
|
623
|
-
- `system/chrome/edge/firefox`: Open specific browser
|
|
624
|
-
|
|
625
|
-
`--browser` and `--redirect-port` are routed into `browserCallbackStrategy`. This CLI has no
|
|
626
|
-
default of its own for the callback port: `--redirect-port` overrides it when given; omitted,
|
|
627
|
-
the port comes from `auth-providers` (currently `61001`, chosen to sit above the ephemeral range
|
|
628
|
-
and clear of the `3001`/`3333` range servers and proxies typically use). If you registered a
|
|
629
|
-
redirect URI with a specific port at your identity provider, pass `--redirect-port` to match it.
|
|
630
|
-
A login is given 5 minutes to complete (this is a person switching to a browser and signing in
|
|
631
|
-
by hand, not an unattended caller).
|
|
632
|
-
|
|
633
|
-
**SAML options (`saml2-pure`, `saml2-bearer`):**
|
|
634
|
-
`mcp-auth` hands these subcommands to `mcp-sso` with every argument unchanged, so the SAML options
|
|
635
|
-
are `mcp-sso`'s (see *CLI: mcp-sso* and *SAML assertion validation* below) and its exit code is
|
|
636
|
-
`mcp-auth`'s. The ones a run needs:
|
|
637
|
-
|
|
638
|
-
| Option | What it is |
|
|
639
|
-
|---|---|
|
|
640
|
-
| `--idp-metadata <url\|path>` | The identity provider's SAML metadata; fills `--idp-cert`, `--idp-entity-id` and `--idp-sso-url`. For SAP Cloud Identity Services: `https://<tenant>.accounts.ondemand.com/saml2/metadata`. |
|
|
641
|
-
| `--idp-cert <path>`, `--idp-entity-id <id>` | The same trust, stated instead of read. |
|
|
642
|
-
| `--idp-initiated` | The identity provider starts the login. `saml2-bearer` against XSUAA needs it. |
|
|
643
|
-
| `--sp-entity-id`, `--acs-url` | The `Audience` and `Recipient`. For `saml2-bearer` with `--service-key`, read from `<uaa.url>/saml/metadata`. |
|
|
644
|
-
| `--assertion <base64>`, `--assertion-flow <flow>` | A `SAMLResponse` obtained elsewhere, or how to obtain one. |
|
|
645
|
-
| `--authn-request-id <id>` | The request an `--assertion` answers, when `mcp-sso` did not send it. |
|
|
646
|
-
|
|
647
|
-
`saml2-bearer` still requires `--dev`: it has not been run against a live XSUAA with a SAML trust.
|
|
648
|
-
|
|
649
|
-
**Examples:**
|
|
650
|
-
```bash
|
|
651
|
-
# Auth code (default via service key)
|
|
652
|
-
mcp-auth auth-code --service-key ./abap.json --output ./abap.env --type abap
|
|
653
|
-
|
|
654
|
-
# OIDC SSO (device flow example)
|
|
655
|
-
mcp-auth oidc --flow device --issuer https://issuer --client-id my-client --output ./sso.env --type xsuaa
|
|
656
|
-
|
|
657
|
-
# SAML2 pure (cookie); the SAML flags are mcp-sso's, see "SAML assertion validation" below
|
|
658
|
-
mcp-auth saml2-pure --idp-sso-url https://idp/sso --sp-entity-id my-sp --idp-cert ./idp-signing.pem --idp-entity-id https://idp.example/metadata --output ./saml.env --type abap
|
|
659
|
-
|
|
660
|
-
# SAML2 bearer (in progress, requires --dev)
|
|
661
|
-
mcp-auth saml2-bearer --dev --service-key ./mcp.json --idp-metadata https://<ias-tenant>.accounts.ondemand.com/saml2/metadata --idp-initiated --output ./sso.env --type xsuaa
|
|
662
|
-
|
|
663
|
-
# ABAP: authorization_code (default, opens browser)
|
|
664
|
-
mcp-auth --service-key ./abap.json --output ./abap.env --type abap
|
|
665
|
-
|
|
666
|
-
# ABAP: authorization_code (show URL in console, no browser)
|
|
667
|
-
mcp-auth --service-key ./abap.json --output ./abap.env --type abap --browser none
|
|
668
|
-
|
|
669
|
-
# XSUAA: authorization_code (default)
|
|
670
|
-
mcp-auth --service-key ./mcp.json --output ./mcp.env --type xsuaa
|
|
671
|
-
|
|
672
|
-
# XSUAA: client_credentials (special cases)
|
|
673
|
-
mcp-auth --service-key ./mcp.json --output ./mcp.env --type xsuaa --credential
|
|
674
|
-
|
|
675
|
-
# Using existing .env for refresh token
|
|
676
|
-
mcp-auth --env ./mcp.env --service-key ./mcp.json --output ./mcp.env --type xsuaa
|
|
677
|
-
```
|
|
678
|
-
|
|
679
|
-
### CLI: mcp-sso
|
|
680
|
-
|
|
681
|
-
Get tokens via SSO providers (OIDC/SAML) and generate `.env`/JSON output:
|
|
682
|
-
|
|
683
|
-
```bash
|
|
684
|
-
mcp-sso <oidc|saml2|bearer> [options]
|
|
685
|
-
mcp-sso --protocol <oidc|saml2> --flow <flow> --output <path> [--type abap|xsuaa] [--format env|json] [--env <path>] [--config <path>]
|
|
686
|
-
```
|
|
687
|
-
|
|
688
|
-
**Supported flows:**
|
|
689
|
-
- OIDC: `browser`, `device`, `password`, `token_exchange`
|
|
690
|
-
- SAML2: `bearer`, `pure`
|
|
691
|
-
|
|
692
|
-
Only the flows that actually open a browser (OIDC `browser`; SAML2 `bearer`/`pure` with the
|
|
693
|
-
default `--assertion-flow browser`) use `--browser` and `--redirect-port` — they are routed
|
|
694
|
-
into `browserCallbackStrategy`/`oidcCallbackStrategy`/`samlCallbackStrategy`. This CLI has no
|
|
695
|
-
default of its own for the callback port: `--redirect-port` overrides it when given; omitted,
|
|
696
|
-
the port comes from `auth-providers` (currently `61001`). A login is given 5 minutes to
|
|
697
|
-
complete. `device`, `password`, and `token_exchange` never open a browser from this process, so
|
|
698
|
-
`--browser`/`--redirect-port` have no effect for them. This applies the same way whether
|
|
699
|
-
`--protocol`/`--flow` come from CLI flags or from `--config` (below) — a field's origin doesn't
|
|
700
|
-
change how it's handled, and CLI flags always take precedence over the same field in a file.
|
|
701
|
-
|
|
702
|
-
**Examples:**
|
|
703
|
-
```bash
|
|
704
|
-
# OIDC browser flow
|
|
705
|
-
mcp-sso oidc --flow browser --issuer https://issuer --client-id my-client --output ./sso.env --type xsuaa
|
|
706
|
-
|
|
707
|
-
# OIDC browser flow (manual code / OOB — no callback server is opened for this combination)
|
|
708
|
-
mcp-sso oidc --flow browser --token-endpoint https://issuer/token --client-id my-client --code <auth_code> --redirect-uri urn:ietf:wg:oauth:2.0:oob --output ./sso.env --type xsuaa
|
|
709
|
-
|
|
710
|
-
# OIDC device flow
|
|
711
|
-
mcp-sso oidc --flow device --issuer https://issuer --client-id my-client --output ./sso.env --type xsuaa
|
|
712
|
-
|
|
713
|
-
# OIDC password flow
|
|
714
|
-
mcp-sso oidc --flow password --token-endpoint https://issuer/oauth/token --client-id my-client --username user --password pass --output ./sso.env --type xsuaa
|
|
715
|
-
|
|
716
|
-
# OIDC token exchange
|
|
717
|
-
mcp-sso oidc --flow token_exchange --issuer https://issuer --client-id my-client --subject-token <token> --output ./sso.env --type xsuaa
|
|
718
|
-
|
|
719
|
-
# SAML bearer flow against XSUAA with a service key: the Audience, Recipient and token alias
|
|
720
|
-
# come from <uaa.url>/saml/metadata, the IdP's trust from its own metadata
|
|
721
|
-
mcp-sso bearer --service-key ./service-key.json --idp-metadata https://<ias-tenant>.accounts.ondemand.com/saml2/metadata --idp-initiated --output ./sso.env --type xsuaa
|
|
722
|
-
|
|
723
|
-
# The same, every value stated (IdP-initiated assertion -> token)
|
|
724
|
-
mcp-sso bearer --idp-sso-url https://idp/sso --sp-entity-id <uaa-entity-id> --acs-url <uaa-bearer-acs> --idp-cert ./idp-signing.pem --idp-entity-id https://idp.example/metadata --idp-initiated --token-endpoint https://uaa.example/oauth/token --assertion <base64> --output ./sso.env --type xsuaa
|
|
725
|
-
|
|
726
|
-
# SAML pure flow (cookie; SP-initiated browser login, the request is sent by mcp-sso)
|
|
727
|
-
mcp-sso saml2 --flow pure --idp-sso-url https://idp/sso --sp-entity-id my-sp --idp-cert ./idp-signing.pem --idp-entity-id https://idp.example/metadata --cookie "SAP_SESSION=..." --output ./sso.env --type abap
|
|
728
|
-
```
|
|
729
|
-
|
|
730
|
-
**SAML assertion validation:**
|
|
731
|
-
Both SAML flows validate every assertion before using it — signature, issuer, audience,
|
|
732
|
-
recipient, time window, request ID and replay (done by `@mcp-abap-adt/auth-providers` 4; see its
|
|
733
|
-
README, *SAML assertion validation*). The provider will not even be constructed without the
|
|
734
|
-
trust it checks against, and `mcp-sso` invents none of it — it is stated, or read from SAML
|
|
735
|
-
metadata:
|
|
736
|
-
|
|
737
|
-
| Option | `--config` field | What it is |
|
|
738
|
-
|---|---|---|
|
|
739
|
-
| `--idp-cert <path>` (repeatable) | `idpCertificates` (string or list, inline PEM or base64 DER) | The identity provider's signing certificate(s). A file may be PEM (one or several certificates) or binary DER. Repeat the flag, or list several, to trust both keys during a rotation. |
|
|
740
|
-
| `--idp-entity-id <id>` | `idpEntityId` | The identity provider's `entityID` — the `Issuer` its assertions carry. |
|
|
741
|
-
| `--idp-metadata <url\|path>` | `idpMetadata` | The identity provider's SAML metadata (for SAP Cloud Identity Services `https://<tenant>.accounts.ondemand.com/saml2/metadata`). Fills the two rows above and `--idp-sso-url` where not given: signing keys and keys without `use`, never encryption keys. An https URL or a file; plain http only for loopback. Federation metadata (an `EntitiesDescriptor` of several entities) works too: entity ID, keys and SSO URL all come from the same identity provider, which `--idp-entity-id` names when there are several — without it such a run stops and lists them. |
|
|
742
|
-
| `--sp-entity-id <id>` | `spEntityId` | Already required; it is now also the `Audience` the assertion must name. For bearer against UAA/XSUAA, the `entityID` in their SAML metadata. |
|
|
743
|
-
| `--acs-url <url>` | `acsUrl` | The `Recipient` the assertion must name. For bearer against UAA/XSUAA, the token endpoint's bearer ACS; the default `http://localhost:<port>/callback` fits only a login delivered to this CLI. |
|
|
744
|
-
| `--idp-initiated` | `idpInitiated` (`true`/`false`) | The identity provider starts the login and no AuthnRequest is sent, so the assertion must carry no `InResponseTo`. |
|
|
745
|
-
| `--authn-request-id <id>` | `authnRequestId` | The AuthnRequest ID an `--assertion` answers, when the request was sent by something other than `mcp-sso`. |
|
|
746
|
-
|
|
747
|
-
A `--idp-cert` on the command line replaces the file's `idpCertificates` rather than adding to
|
|
748
|
-
them, so a certificate retired on the command line is not still trusted from the file.
|
|
749
|
-
|
|
750
|
-
Which request setting a run needs:
|
|
751
|
-
|
|
752
|
-
- **Browser or manual login, SP-initiated** (`--assertion-flow browser`, the default, or
|
|
753
|
-
`manual`): nothing — `mcp-sso` builds the AuthnRequest and knows its ID.
|
|
754
|
-
- **`--assertion <base64>`** from an SP-initiated login sent elsewhere: `--authn-request-id`.
|
|
755
|
-
- **IdP-initiated** — required for `bearer` against UAA or XSUAA, whose saml2-bearer grant refuses
|
|
756
|
-
an assertion carrying `InResponseTo`: `--idp-initiated`, with `--assertion`, or with
|
|
757
|
-
`--assertion-flow manual` (the default under `--idp-initiated`), which asks you to start the
|
|
758
|
-
login at the identity provider and paste the `SAMLResponse` it posts. `--idp-initiated` with
|
|
759
|
-
`--assertion-flow browser` is refused, since there is no request URL to open.
|
|
760
|
-
|
|
761
|
-
`--idp-initiated` together with `--authn-request-id`, a missing certificate or entity ID, or an
|
|
762
|
-
assertion that fails a check is reported by `auth-providers` itself (`ValidationError` or
|
|
763
|
-
`AssertionValidationError`), with the field or the check it refused.
|
|
764
|
-
|
|
765
|
-
**XSUAA's side of a bearer run:**
|
|
766
|
-
None of `--sp-entity-id`, `--acs-url` and the bearer token endpoint is in an XSUAA service key, but
|
|
767
|
-
XSUAA publishes all three in its SAML metadata: its `entityID` is the `Audience`, and its
|
|
768
|
-
`/oauth/token/alias/<alias>` endpoint is both the `Recipient` and where the assertion is exchanged.
|
|
769
|
-
With `--service-key`, `bearer` reads `<uaa.url>/saml/metadata` and fills whichever of them was not
|
|
770
|
-
given. Without network access to it, pass the file (from *Security > Trust Configuration >
|
|
771
|
-
Download SAML Metadata* in the subaccount):
|
|
772
|
-
|
|
773
|
-
```bash
|
|
774
|
-
mcp-sso bearer --saml-metadata ./saml-sp.xml --idp-sso-url https://idp/sso --sp-entity-id <uaa-entity-id> --acs-url <uaa-bearer-acs> --idp-cert ./idp-signing.pem --idp-entity-id https://idp.example/metadata --idp-initiated --assertion <base64> --service-key ./service-key.json --output ./sso.env --type xsuaa
|
|
775
|
-
```
|
|
776
|
-
|
|
777
|
-
### Local Keycloak (OIDC + SAML Tests)
|
|
778
|
-
|
|
779
|
-
For local testing of `mcp-sso`, a ready-to-run Keycloak setup is included
|
|
780
|
-
(OIDC browser/password/device + SAML assertion capture).
|
|
781
|
-
|
|
782
|
-
```bash
|
|
783
|
-
cd tests/keycloak
|
|
784
|
-
docker compose up -d
|
|
785
|
-
```
|
|
786
|
-
|
|
787
|
-
Then use:
|
|
788
|
-
```bash
|
|
789
|
-
node dist/bin/mcp-sso.js \
|
|
790
|
-
oidc \
|
|
791
|
-
--flow browser \
|
|
792
|
-
--issuer http://localhost:8080/realms/mcp-sso \
|
|
793
|
-
--client-id mcp-sso-cli \
|
|
794
|
-
--scopes openid,profile,email \
|
|
795
|
-
--output /tmp/keycloak.env \
|
|
796
|
-
--type xsuaa
|
|
797
|
-
```
|
|
798
|
-
|
|
799
|
-
See `tests/keycloak/README.md` for device flow and SAML examples.
|
|
800
|
-
|
|
801
|
-
### XSUAA Demo (CAP)
|
|
802
|
-
|
|
803
|
-
A minimal CAP app for testing XSUAA flows is included at `tests/sso-demo`.
|
|
804
|
-
It enables `authorization_code` and `saml2-bearer` grant types and provides a
|
|
805
|
-
simple `CatalogService`. See `tests/sso-demo/readme.md` for deploy steps.
|
|
806
|
-
|
|
807
|
-
**Config file:**
|
|
808
|
-
You can pass a JSON file with provider config instead of (or alongside) `--protocol`/`--flow`
|
|
809
|
-
and the OIDC/SAML flags — `--config` alone is enough to run a flow, with no other flags required:
|
|
810
|
-
|
|
811
|
-
```json
|
|
812
|
-
{
|
|
813
|
-
"protocol": "oidc",
|
|
814
|
-
"flow": "device",
|
|
815
|
-
"issuerUrl": "https://issuer",
|
|
816
|
-
"clientId": "my-client",
|
|
817
|
-
"scopes": ["openid", "profile"]
|
|
818
|
-
}
|
|
819
|
-
```
|
|
820
|
-
|
|
821
|
-
Any CLI flag given alongside `--config` overrides the same field in the file; a field the file
|
|
822
|
-
sets and no flag overrides is used as-is. A file written for a pre-2.0.0 config still works:
|
|
823
|
-
`browser` and `redirectPort` are routed into the strategy exactly as the equivalent CLI flags
|
|
824
|
-
are, and `authorizationCode`/`assertionFlow` are honored the same way `--code`/`--assertion-flow`
|
|
825
|
-
are. A file that sets `authorizationCodeProvider`, `assertionProvider`, or `manualInput` — all
|
|
826
|
-
functions, which JSON cannot express — is refused with an error naming the CLI flag to use
|
|
827
|
-
instead, rather than having the field silently dropped.
|
|
828
|
-
|
|
829
|
-
A SAML config file carries the trust inline:
|
|
830
|
-
|
|
831
|
-
```json
|
|
832
|
-
{
|
|
833
|
-
"protocol": "saml2",
|
|
834
|
-
"flow": "bearer",
|
|
835
|
-
"idpSsoUrl": "https://idp.example/sso",
|
|
836
|
-
"spEntityId": "https://uaa.example/entity",
|
|
837
|
-
"acsUrl": "https://uaa.example/oauth/token/alias/example",
|
|
838
|
-
"idpEntityId": "https://idp.example/metadata",
|
|
839
|
-
"idpCertificates": ["MIIC...base64 DER from the IdP metadata's <X509Certificate>..."],
|
|
840
|
-
"idpInitiated": true,
|
|
841
|
-
"assertionFlow": "manual"
|
|
842
|
-
}
|
|
843
|
-
```
|
|
844
|
-
|
|
845
|
-
#### Migrating `mcp-sso` SAML runs from 2.2.0
|
|
846
|
-
|
|
847
|
-
2.2.0 used `@mcp-abap-adt/auth-providers` 2.x, which trusted any SAML payload it was handed.
|
|
848
|
-
With 4.x every `mcp-sso` SAML run (`bearer`, `saml2 --flow pure`, and `mcp-auth saml2-pure` /
|
|
849
|
-
`saml2-bearer`, which call it) fails before login until you add:
|
|
850
|
-
|
|
851
|
-
1. `--idp-metadata <url|path>`, or `--idp-cert <path>` and `--idp-entity-id <id>` (or
|
|
852
|
-
`idpCertificates` and `idpEntityId` in `--config`) — without them the provider refuses to
|
|
853
|
-
construct.
|
|
854
|
-
2. The real `--sp-entity-id` (the `Audience`) and, unless the assertion is delivered to this CLI's
|
|
855
|
-
own callback, the `--acs-url` it names as `Recipient`. For `bearer` with `--service-key` both
|
|
856
|
-
are read from XSUAA's metadata.
|
|
857
|
-
3. For `bearer` against UAA or XSUAA: `--idp-initiated`, with `--assertion` or
|
|
858
|
-
`--assertion-flow manual`. For any other `--assertion` from an SP-initiated login:
|
|
859
|
-
`--authn-request-id`.
|
|
860
|
-
|
|
861
|
-
Node.js 22, 24 or 26 is required.
|
|
862
|
-
|
|
863
|
-
### Utility Script
|
|
864
|
-
|
|
865
|
-
Generate `.env` files from service keys:
|
|
866
|
-
|
|
867
|
-
```bash
|
|
868
|
-
npm run generate-env <destination> [service-key-path] [session-path]
|
|
869
|
-
```
|
|
870
|
-
|
|
871
609
|
## Testing
|
|
872
610
|
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
### Running Tests
|
|
611
|
+
The library's tests are in `packages/auth-broker/src/__tests__/` and use Jest.
|
|
612
|
+
Run them from the repository root, where the dev dependencies are installed:
|
|
876
613
|
|
|
877
614
|
```bash
|
|
878
|
-
#
|
|
615
|
+
# Every workspace's tests (library and CLI)
|
|
879
616
|
npm test
|
|
880
617
|
|
|
881
|
-
#
|
|
882
|
-
npm test
|
|
883
|
-
npm test -- refreshToken.test.ts
|
|
618
|
+
# The library's only
|
|
619
|
+
npm test -w @mcp-abap-adt/auth-broker
|
|
884
620
|
|
|
885
|
-
#
|
|
886
|
-
npm test --
|
|
887
|
-
npm test --
|
|
888
|
-
npm test -- getToken.test.ts -t "Test 3"
|
|
889
|
-
|
|
890
|
-
# Run test group (e.g., all getToken tests)
|
|
891
|
-
npm test -- getToken.test.ts
|
|
892
|
-
|
|
893
|
-
# Note: Test 2 requires Test 1 to pass first (test1Passed flag)
|
|
894
|
-
# To run Test 2 alone, you may need to run all tests in the file:
|
|
895
|
-
npm test -- getToken.test.ts
|
|
621
|
+
# One file, or one case
|
|
622
|
+
npm test -w @mcp-abap-adt/auth-broker -- AuthBroker.test.ts
|
|
623
|
+
npm test -w @mcp-abap-adt/auth-broker -- AuthBroker.test.ts -t "name of the case"
|
|
896
624
|
```
|
|
897
625
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
- Requires: `NO_EXISTS.json` should NOT exist
|
|
904
|
-
|
|
905
|
-
2. **Test 2**: Tests browser authentication when service key exists but `.env` file doesn't
|
|
906
|
-
- Requires: `TRIAL.json` must exist, `TRIAL.env` should NOT exist
|
|
907
|
-
- Will open browser for OAuth authentication
|
|
908
|
-
|
|
909
|
-
3. **Test 3**: Tests token refresh using existing `.env` file
|
|
910
|
-
- Requires: `TRIAL.json` and `TRIAL.env` must exist
|
|
911
|
-
- Can run independently if `.env` file exists (created manually or by Test 2)
|
|
626
|
+
Tests run sequentially (`maxWorkers: 1` and `maxConcurrency: 1` in
|
|
627
|
+
`packages/auth-broker/jest.config.js`). `AuthBroker.test.ts` needs nothing;
|
|
628
|
+
`AuthBroker.integration.test.ts` reads real service keys and sessions, and
|
|
629
|
+
every case in it returns early unless the configuration below names a real
|
|
630
|
+
destination.
|
|
912
631
|
|
|
913
632
|
### Test Setup
|
|
914
633
|
|
|
915
|
-
1. Copy `tests/test-config.yaml.template` to
|
|
634
|
+
1. Copy `packages/auth-broker/tests/test-config.yaml.template` to
|
|
635
|
+
`packages/auth-broker/tests/test-config.yaml` (until the workspace layout it
|
|
636
|
+
lived in `tests/` at the repository root; move an existing copy)
|
|
916
637
|
2. Fill in configuration values (paths, destinations, MCP URL for XSUAA)
|
|
917
638
|
3. Place service key files in configured `service_keys_dir`:
|
|
918
639
|
- `{destination}.json` for ABAP tests (e.g., `trial.json`)
|
|
919
640
|
- `{btp_destination}.json` for XSUAA tests (e.g., `btp.json`)
|
|
920
641
|
|
|
921
|
-
|
|
642
|
+
Without `test-config.yaml` the template is read, its placeholders disable every
|
|
643
|
+
integration case, and the run reaches no system.
|
|
922
644
|
|
|
923
645
|
## Documentation
|
|
924
646
|
|
|
925
|
-
Complete documentation is available in the [`docs/`](docs/) directory:
|
|
647
|
+
Complete documentation is available in the repository's [`docs/`](../../docs/) directory:
|
|
926
648
|
|
|
927
|
-
- **[Architecture](docs/architecture/ARCHITECTURE.md)** - System architecture and design decisions
|
|
928
|
-
- **[Development](docs/development/)** - Testing methodology and development roadmap
|
|
929
|
-
- **[Development Roadmap](docs/development/DEVELOPMENT_ROADMAP.md)** - Development roadmap and future plans
|
|
930
|
-
- **[Installation](docs/installing/INSTALLATION.md)** - Installation and setup guide
|
|
931
|
-
- **[Usage](docs/using/USAGE.md)** - API reference and usage examples
|
|
649
|
+
- **[Architecture](../../docs/architecture/ARCHITECTURE.md)** - System architecture and design decisions
|
|
650
|
+
- **[Development](../../docs/development/)** - Testing methodology and development roadmap
|
|
651
|
+
- **[Development Roadmap](../../docs/development/DEVELOPMENT_ROADMAP.md)** - Development roadmap and future plans
|
|
652
|
+
- **[Installation](../../docs/installing/INSTALLATION.md)** - Installation and setup guide
|
|
653
|
+
- **[Usage](../../docs/using/USAGE.md)** - API reference and usage examples
|
|
932
654
|
|
|
933
|
-
See [docs/README.md](docs/README.md) for the complete documentation index.
|
|
655
|
+
See [docs/README.md](../../docs/README.md) for the complete documentation index.
|
|
934
656
|
|
|
935
657
|
## Contributors
|
|
936
658
|
|
|
937
|
-
Thank you to all contributors! See [CONTRIBUTORS.md](CONTRIBUTORS.md) for the complete list.
|
|
659
|
+
Thank you to all contributors! See [CONTRIBUTORS.md](../../CONTRIBUTORS.md) for the complete list.
|
|
938
660
|
|
|
939
661
|
## License
|
|
940
662
|
|
package/package.json
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-abap-adt/auth-broker",
|
|
3
|
-
"version": "3.0
|
|
4
|
-
"description": "Per-destination token broker for SAP BTP and ABAP: sessions and service keys from stores, tokens from an injected provider, results persisted
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "Per-destination token broker for SAP BTP and ABAP: sessions and service keys from stores, tokens from an injected provider, results persisted",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist",
|
|
9
9
|
"README.md",
|
|
10
10
|
"CHANGELOG.md",
|
|
11
|
-
"CONTRIBUTORS.md",
|
|
12
11
|
"LICENSE",
|
|
13
12
|
"COPYING"
|
|
14
13
|
],
|
|
@@ -24,70 +23,44 @@
|
|
|
24
23
|
"abap-adt",
|
|
25
24
|
"xsuaa",
|
|
26
25
|
"oauth2",
|
|
27
|
-
"saml"
|
|
28
|
-
"sso"
|
|
26
|
+
"saml"
|
|
29
27
|
],
|
|
30
28
|
"author": "Oleksii Kyslytsia <oleksij.kyslytsja@gmail.com>",
|
|
31
29
|
"license": "LGPL-3.0-only",
|
|
32
|
-
"homepage": "https://github.com/fr0ster/mcp-abap-adt-auth-broker#readme",
|
|
30
|
+
"homepage": "https://github.com/fr0ster/mcp-abap-adt-auth-broker/tree/main/packages/auth-broker#readme",
|
|
33
31
|
"bugs": {
|
|
34
32
|
"url": "https://github.com/fr0ster/mcp-abap-adt-auth-broker/issues"
|
|
35
33
|
},
|
|
36
34
|
"repository": {
|
|
37
35
|
"type": "git",
|
|
38
|
-
"url": "git+https://github.com/fr0ster/mcp-abap-adt-auth-broker.git"
|
|
36
|
+
"url": "git+https://github.com/fr0ster/mcp-abap-adt-auth-broker.git",
|
|
37
|
+
"directory": "packages/auth-broker"
|
|
39
38
|
},
|
|
40
39
|
"publishConfig": {
|
|
41
40
|
"access": "public"
|
|
42
41
|
},
|
|
43
42
|
"scripts": {
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"lint": "biome check --write src",
|
|
47
|
-
"lint:check": "biome check src",
|
|
48
|
-
"format": "biome format --write src",
|
|
49
|
-
"build": "npm run --silent clean && biome check src --diagnostic-level=error && tsc -p tsconfig.json && tsc -p tsconfig.cli.json",
|
|
50
|
-
"build:fast": "tsc -p tsconfig.json && tsc -p tsconfig.cli.json",
|
|
43
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo tsconfig.build.tsbuildinfo",
|
|
44
|
+
"build": "tsc -b tsconfig.build.json",
|
|
51
45
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
|
|
52
|
-
"test:check": "tsc
|
|
53
|
-
"
|
|
54
|
-
"test:mcp-sso": "sh tests/sso-demo/run-mcp-sso.sh",
|
|
55
|
-
"test:device-code": "sh tests/keycloak/run-oidc.sh",
|
|
56
|
-
"test:saml-pure": "sh tests/keycloak/run-saml.sh",
|
|
57
|
-
"test:sso": "sh tests/keycloak/run-interactive.sh",
|
|
58
|
-
"prepublishOnly": "npm run build",
|
|
59
|
-
"prepack": "npm run build",
|
|
60
|
-
"generate-env": "tsx bin/generate-env-from-service-key.ts"
|
|
61
|
-
},
|
|
62
|
-
"bin": {
|
|
63
|
-
"mcp-auth": "./dist/bin/mcp-auth.js",
|
|
64
|
-
"mcp-sso": "./dist/bin/mcp-sso.js"
|
|
46
|
+
"test:check": "tsc -p tsconfig.json --noEmit",
|
|
47
|
+
"prepublishOnly": "npm run --prefix ../.. check"
|
|
65
48
|
},
|
|
66
49
|
"engines": {
|
|
67
50
|
"node": "^22 || ^24 || ^26"
|
|
68
51
|
},
|
|
69
52
|
"dependencies": {
|
|
70
|
-
"@mcp-abap-adt/auth-providers": "^4.2.0",
|
|
71
|
-
"@mcp-abap-adt/auth-stores": "^1.2.3",
|
|
72
53
|
"@mcp-abap-adt/interfaces-auth": "^2.1.0",
|
|
73
54
|
"@mcp-abap-adt/interfaces-auth-sap": "^1.0.1",
|
|
74
|
-
"@mcp-abap-adt/interfaces-utils": "^1.1.0"
|
|
75
|
-
"axios": "^1.13.5"
|
|
55
|
+
"@mcp-abap-adt/interfaces-utils": "^1.1.0"
|
|
76
56
|
},
|
|
77
57
|
"devDependencies": {
|
|
78
|
-
"@
|
|
58
|
+
"@mcp-abap-adt/auth-providers": "^4.2.0",
|
|
59
|
+
"@mcp-abap-adt/auth-stores": "^1.2.3",
|
|
79
60
|
"@mcp-abap-adt/logger": "^0.4.0",
|
|
80
|
-
"@types/express": "^5.0.5",
|
|
81
|
-
"@types/jest": "^30.0.0",
|
|
82
61
|
"@types/js-yaml": "^4.0.9",
|
|
83
|
-
"@types/node": "^25.2.3",
|
|
84
|
-
"jest": "^30.2.0",
|
|
85
|
-
"jest-util": "^30.2.0",
|
|
86
62
|
"js-yaml": "^4.1.1",
|
|
87
63
|
"pino": "^10.1.0",
|
|
88
|
-
"pino-pretty": "^13.1.3"
|
|
89
|
-
"ts-jest": "^29.2.5",
|
|
90
|
-
"tsx": "^4.21.0",
|
|
91
|
-
"typescript": "^5.9.2"
|
|
64
|
+
"pino-pretty": "^13.1.3"
|
|
92
65
|
}
|
|
93
66
|
}
|
package/CONTRIBUTORS.md
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# Contributors
|
|
2
|
-
|
|
3
|
-
Thank you to all contributors who have helped make `@mcp-abap-adt/auth-broker` better!
|
|
4
|
-
|
|
5
|
-
## How to Contribute
|
|
6
|
-
|
|
7
|
-
We welcome contributions! Please see the project documentation for details on how to get started.
|
|
8
|
-
|
|
9
|
-
## Contributors
|
|
10
|
-
|
|
11
|
-
<!-- Contributors are listed alphabetically by last name -->
|
|
12
|
-
|
|
13
|
-
### Core Contributors
|
|
14
|
-
|
|
15
|
-
- **Oleksii Kyslytsia** - Project creator and maintainer
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Recognition
|
|
20
|
-
|
|
21
|
-
We appreciate every contribution, whether it's:
|
|
22
|
-
- 🐛 Bug reports and fixes
|
|
23
|
-
- ✨ New features and enhancements
|
|
24
|
-
- 📚 Documentation improvements
|
|
25
|
-
- 🧪 Test coverage
|
|
26
|
-
- 💬 Feedback and suggestions
|
|
27
|
-
|
|
28
|
-
Every contribution helps make `@mcp-abap-adt/auth-broker` better for everyone!
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
**Note:** This list is manually maintained. If you've contributed but don't see your name here, please open an issue or submit a PR to update this file.
|
|
33
|
-
|