@mcp-abap-adt/core 6.8.0 → 6.9.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 +11 -0
- package/README.md +38 -0
- package/dist/lib/config/applyAuthFields.d.ts +8 -0
- package/dist/lib/config/applyAuthFields.d.ts.map +1 -0
- package/dist/lib/config/applyAuthFields.js +30 -0
- package/dist/lib/config/applyAuthFields.js.map +1 -0
- package/dist/lib/config/parseAuthType.d.ts +4 -0
- package/dist/lib/config/parseAuthType.d.ts.map +1 -0
- package/dist/lib/config/parseAuthType.js +22 -0
- package/dist/lib/config/parseAuthType.js.map +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +6 -15
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +11 -16
- package/dist/lib/utils.js.map +1 -1
- package/docs/superpowers/plans/2026-05-23-cert-kerberos-auth.md +652 -0
- package/docs/superpowers/plans/innovations-from-sap-adt-mcp.md +103 -0
- package/docs/superpowers/specs/2026-05-23-cert-kerberos-auth-design.md +149 -0
- package/package.json +3 -3
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# План інновацій з аналізу `sap-adt-mcp`
|
|
2
|
+
|
|
3
|
+
> Джерело: `~/prj/sap-adt-mcp` (окремий open-source MCP-сервер для SAP ADT, TS, MCP SDK v1.x).
|
|
4
|
+
> Мета цього документа — зафіксувати, що з їхніх рішень варто перенести до нашого стеку,
|
|
5
|
+
> у який саме компонент/пакет це лягає, який буст дає, і що ми дивимось «для довідки», але собі не робимо.
|
|
6
|
+
>
|
|
7
|
+
> Це **план-кошик ідей**, а не план імплементації. Рішення «що/де робити» приймаємо окремо по кожному пункту.
|
|
8
|
+
|
|
9
|
+
## Контекст нашого стеку (важливо для оцінки вартості)
|
|
10
|
+
|
|
11
|
+
На відміну від `sap-adt-mcp` (моноліт: один процес, один `.sap-profiles.json`, axios усередині),
|
|
12
|
+
у нас функціонал розкладений по пакетах:
|
|
13
|
+
|
|
14
|
+
- **mcp-abap-adt** — MCP-сервер (handlers, server transport, auth broker factory `src/lib/auth/`).
|
|
15
|
+
- **mcp-abap-adt-clients** — ADT-клієнти (`AdtClient`, `AdtClientLegacy`, executors, core).
|
|
16
|
+
- **пакет-конектор** — нижній шар з'єднання/сесії.
|
|
17
|
+
- (+ типи/спільні утиліти).
|
|
18
|
+
|
|
19
|
+
**Наслідок для авторизації:** будь-яка зміна способу автентифікації зачіпає **3 пакети + конектор**,
|
|
20
|
+
а не один файл як у них. Тому auth — найдорожчий і найважливіший блок: оцінюємо окремо й обережно.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## A. Авторизація (найвищий пріоритет, найдорожче)
|
|
25
|
+
|
|
26
|
+
У `sap-adt-mcp` три способи auth у профілі (`.sap-profiles.json`): `basic`, `certificate`, `kerberos`.
|
|
27
|
+
Системи — **тільки on-prem ADT** (ICM HTTPS 44300). Cloud/BTP (JWT/OAuth) у них немає — тут ми попереду.
|
|
28
|
+
|
|
29
|
+
| # | Інновація | Як у них | Що дає нам | Куди лягає | Вартість | Буст |
|
|
30
|
+
|---|-----------|----------|------------|------------|----------|------|
|
|
31
|
+
| A1 | **Certificate Auth (Windows Cert Store)** | PowerShell+SChannel bridge, пошук серта по SHA-1 thumbprint, без пароля | Закриває корпоративні on-prem системи, де basic заборонений, а вхід — по клієнтському серту | конектор + clients + broker factory + типи профілю | Висока (3 пакети + конектор, Windows-only, spawn PowerShell) | Високий для enterprise on-prem; нульовий для cloud |
|
|
32
|
+
| A2 | **Kerberos / SPNEGO SSO** | `kerberos` npm, SPN `HTTP@host`, NTLM-detection + hard-reject | Доменний SSO без зберігання пароля — велика зручність і безпека на on-prem | конектор + clients + broker factory | Висока (нативний модуль компілюється з C++, Windows-домен) | Високий для доменних on-prem; вузька аудиторія |
|
|
33
|
+
| A3 | **NTLM-detection guard** | перевірка base64-префікса `TlRMTVNTUAA`, відмова якщо прийшов NTLM замість Kerberos | Захист від тихого фолбеку на слабкий NTLM | конектор | Низька (окрема функція) | Точковий, але дешевий — варто взяти разом з A2 |
|
|
34
|
+
|
|
35
|
+
**Рекомендація:** спочатку design-spike — описати, як certificate/kerberos лягають на наш broker factory
|
|
36
|
+
+ конектор **без ламання** cloud(JWT)/RFC шляхів. Реалізацію A1/A2 — лише після окремого рішення,
|
|
37
|
+
бо ціна висока, а аудиторія вузька (доменні Windows on-prem).
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## B. Інструменти читання / навігації (середня ціна, хороший буст)
|
|
42
|
+
|
|
43
|
+
| # | Інновація | Що дає нам | Куди лягає | Вартість | Буст |
|
|
44
|
+
|---|-----------|------------|------------|----------|------|
|
|
45
|
+
| B1 | **`read_signatures`** — лише PUBLIC SECTION класу (методи/типи/константи, без тіл) | 5–20× менший контекст для LLM коли треба лише інтерфейс класу. Прямий burn-rate виграш токенів | handler + clients (парс public section) | Низька–середня | **Високий** — економія токенів на кожному читанні класу |
|
|
46
|
+
| B2 | **`list_method_callers`** — where-used на рівні методу | Точніший impact-аналіз перед зміною методу (не весь клас) | handler + clients (method-level usageReferences) | Середня | Середній — корисно для рефакторингу |
|
|
47
|
+
| B3 | **`get_cds_dependencies` з SQL-метриками** — дерево залежностей CDS + joins/unions/views count + complexity score (LOW…VERY_HIGH) + DCL/ACL стан | Швидка оцінка складності/безпеки CDS без ручного читання | handler + clients (cds dependency graph parse) | Середня | Середній — нішево для CDS-важких проєктів |
|
|
48
|
+
| B4 | **`browse_package` без 500-cap** (до 9999) | Повний лістинг великих пакетів за раз | перевірити, чи в нас є cap; якщо є — підняти | Низька | Низький–середній (залежить чи є в нас обмеження) |
|
|
49
|
+
|
|
50
|
+
**Рекомендація:** **B1 — взяти першим.** Дешево, прямий і вимірюваний виграш по токенах для будь-якого
|
|
51
|
+
агентного сценарію. B2/B3 — за запитом.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## C. Безпека запису / гардрейли (дешево, добрий ROI)
|
|
56
|
+
|
|
57
|
+
| # | Інновація | Що дає нам | Куди лягає | Вартість | Буст |
|
|
58
|
+
|---|-----------|------------|------------|----------|------|
|
|
59
|
+
| C1 | **`read_table` як SQL Console з guard'ами** — whitelist лише SELECT (блок INSERT/UPDATE/DELETE/MODIFY/CALL/CREATE/DROP/ALTER як перший токен) + blacklist sensitive-таблиць (USR02, USR40, PA000x, T000, RFCDES, DEVACCESS, ICF*) | Безпечний ad-hoc SELECT через ADT SQL Console з захистом від витоку credentials/HR/конфіг даних | handler + clients (sqlConsole endpoint) | Середня | Середній — зручно, але треба ретельні guard'и |
|
|
60
|
+
| C2 | **`namespace` write-guard як middleware** — відхиляє запис до об'єктів не з дозволеним префіксом ще до lock | Захист від випадкового запису поза Z-простором | server middleware / guards | Низька | Середній — дешевий запобіжник |
|
|
61
|
+
| C3 | **per-profile `readonly` + глобальний readonly mode** | Inspection-only режим на рівні профілю/сервера | config + guards | Низька | Середній |
|
|
62
|
+
| C4 | **Mandatory transport для write** | Жодного тихого запису без TR | guards (перевірити чи вже є) | Низька | Залежить від поточного стану |
|
|
63
|
+
|
|
64
|
+
**Рекомендація:** C2/C3/C4 — дешеві запобіжники, варто звірити з тим, що вже маємо, і добрати відсутнє.
|
|
65
|
+
C1 — корисний, але guard'и треба робити консервативно (краще blacklist + whitelist разом).
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## D. UX / onboarding (низький пріоритет для нас)
|
|
70
|
+
|
|
71
|
+
| # | Інновація | Що дає нам | Вартість | Рішення |
|
|
72
|
+
|---|-----------|------------|----------|---------|
|
|
73
|
+
| D1 | **`switch_system`** — runtime-перемикання профілю в одній MCP-сесії | Без рестарту сервера між системами | Середня | Розглянути — у нас multi-session модель може робити це інакше |
|
|
74
|
+
| D2 | **Setup wizard** (`--setup`) з парсингом `SAPUILandscape.xml` + Windows cert listing | Гарний онбординг для desktop-користувача | Висока | Дивимось як ідею, **собі не робимо** — у нас env/конфіг-driven підхід |
|
|
75
|
+
| D3 | **`--standards <file>`** — ін'єкція ABAP coding standards у контекст інструментів | Команда нав'язує naming/error-handling конвенції LLM-у | Низька | **Цікаво — варто розглянути**, дешево й корисно |
|
|
76
|
+
| D4 | **Throttle layer** (acquire/release семафор перед ADT-викликом) | Захист від перевантаження ADT паралельними викликами | Низька–середня | Розглянути якщо ловимо rate-limit/race на ADT |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## E. «Дивимось як у людей, але собі точно не робимо»
|
|
81
|
+
|
|
82
|
+
- **Моноліт-архітектура** (`.sap-profiles.json`, axios усередині сервера) — наш розклад по пакетах
|
|
83
|
+
дає перевикористання клієнтів поза MCP; назад до моноліту не йдемо.
|
|
84
|
+
- **Setup wizard з парсингом `SAPUILandscape.xml`** (D2) — desktop-онбординг, не наш сценарій.
|
|
85
|
+
- **PowerShell-bridge як єдина реалізація cert-auth** — якщо й робити cert-auth (A1), то крос-платформно
|
|
86
|
+
через конектор, а не spawn PowerShell.
|
|
87
|
+
- **Прив'язка до Windows** загалом — у них cert/kerberos Windows-only; нам потрібна крос-платформність.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Підсумкова черга (чернетка, обговорюється)
|
|
92
|
+
|
|
93
|
+
1. **B1 `read_signatures`** — найкращий ROI (токени), низька ціна. Брати першим.
|
|
94
|
+
2. **C2/C3/C4** — звірити наявні гардрейли, добрати дешеві запобіжники.
|
|
95
|
+
3. **A (auth) design-spike** — спроєктувати certificate/kerberos на broker factory + конектор,
|
|
96
|
+
оцінити реальну ціну по 3 пакетах, **рішення про реалізацію — окремо**.
|
|
97
|
+
4. **D3 `--standards`** — дешево, корисно для команд.
|
|
98
|
+
5. **C1 `read_table`/SQL Console** — за наявності guard-бюджету.
|
|
99
|
+
6. **B2/B3** — за запитом конкретних проєктів.
|
|
100
|
+
7. **D1/D4** — розглянути за потребою.
|
|
101
|
+
|
|
102
|
+
> Наступний крок: по кожному пункту з 1–6 — окреме рішення «робимо / в який пакет / коли»
|
|
103
|
+
> + (для auth) окремий технічний spike перед будь-яким кодом.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Spec: Certificate (mTLS) + Kerberos auth across the ADT connection stack
|
|
2
|
+
|
|
3
|
+
> Status: design approved, ready for implementation planning.
|
|
4
|
+
> Lifecycle: this spec lives only in `mcp-abap-adt`. **Delete after implementation** — history stays in git.
|
|
5
|
+
> Source of idea: analysis of `sap-adt-mcp` (see `docs/superpowers/plans/innovations-from-sap-adt-mcp.md`, item A).
|
|
6
|
+
|
|
7
|
+
## 1. Goal & scope
|
|
8
|
+
|
|
9
|
+
Add two new authentication types to the ADT connection stack:
|
|
10
|
+
|
|
11
|
+
- **`certificate`** — client-certificate mutual TLS (mTLS), cross-platform, credential material loaded from **files** (PEM or PFX/PKCS#12).
|
|
12
|
+
- **`kerberos`** — SPNEGO/Negotiate SSO, cross-platform via the `kerberos` npm package (GSSAPI on Linux/macOS, SSPI on Windows), as an **optional dependency**.
|
|
13
|
+
|
|
14
|
+
**In scope:** on-prem ABAP over **HTTP** (`connectionType: 'http'`). Both new types are invalid for `connectionType: 'rfc'` and for BTP cloud (which stays `jwt`).
|
|
15
|
+
|
|
16
|
+
**Out of scope (explicitly NOT building):**
|
|
17
|
+
- Windows Certificate Store / PowerShell-SChannel bridge (the `sap-adt-mcp` approach). Cross-platform file-based only.
|
|
18
|
+
- NTLM. We hard-reject NTLM tokens if a server offers only NTLM (see Risks).
|
|
19
|
+
- Kerberos mutual-auth multi-leg continuation (see Assumptions).
|
|
20
|
+
- RFC-transport variants of these auth types.
|
|
21
|
+
|
|
22
|
+
## 2. Architecture decision (the core call)
|
|
23
|
+
|
|
24
|
+
**Both new auth types bypass `@mcp-abap-adt/auth-broker` and `@mcp-abap-adt/auth-providers` entirely.** The broker's role is narrow: OAuth-style authorization with browser-callback interception. Certificate and Kerberos are non-interactive and transport/connection-level — no browser callback, no broker token lifecycle. They live in the **connection** package (+ types in `interfaces`, + env wiring in the server).
|
|
25
|
+
|
|
26
|
+
| Type | Pattern | Why |
|
|
27
|
+
|------|---------|-----|
|
|
28
|
+
| **Certificate** | Connection subclass + `httpsAgent` options, with an injected `ICertificateMaterialLoader` for testability | The credential is `cert`+private-key used in the **TLS handshake via `httpsAgent`** — transport-layer, below `getAuthHeaders()`. No header/cookie to "provide". |
|
|
29
|
+
| **Kerberos** | Connection subclass that generates the SPNEGO token **locally** (lazy/optional `kerberos` npm wrapper inside the connection package), sends `Authorization: Negotiate <token>` on the first request, then reuses the SAP session cookie | The Negotiate blob goes into a header, but generation is local GSSAPI (no callback, no refresh lifecycle). No broker, no `ITokenRefresher`, no `BaseTokenProvider`. |
|
|
30
|
+
|
|
31
|
+
`@mcp-abap-adt/connection` depends only on `interfaces` + `sap-rfc-lite` (not on `auth-providers`), so the SPNEGO wrapper lives in `connection`, keeping that dependency boundary intact.
|
|
32
|
+
|
|
33
|
+
### Kerberos handshake = single-leg, cookie reuse
|
|
34
|
+
|
|
35
|
+
`AbstractAbapConnection` already owns CSRF fetch + cookie capture/reuse (`fetchCsrfToken`, cookie merge). `KerberosAbapConnection` generates one AP-REQ for the SPN, sends `Authorization: Negotiate <token>` on the first request, captures the SAP session cookie (`SAP_SESSIONID`/`MYSAPSSO2`), and reuses the cookie thereafter. Single-leg only (no mutual-auth continuation in v1 — see Assumptions).
|
|
36
|
+
|
|
37
|
+
## 3. Per-package changes
|
|
38
|
+
|
|
39
|
+
**Three repos** (auth-broker and auth-providers are NOT touched). Listed in dependency (release) order — see §7.
|
|
40
|
+
|
|
41
|
+
### 3.1 `@mcp-abap-adt/interfaces` (`~/prj/mcp-abap-adt-interfaces`)
|
|
42
|
+
|
|
43
|
+
- `src/sap/SapAuthType.ts`: extend union →
|
|
44
|
+
`export type SapAuthType = 'basic' | 'jwt' | 'saml' | 'certificate' | 'kerberos';`
|
|
45
|
+
- `src/sap/ISapConfig.ts`: add optional fields:
|
|
46
|
+
- Certificate: `certPath?`, `certKeyPath?`, `certPfxPath?`, `certPassphrase?`. (PEM = certPath+certKeyPath; PFX = certPfxPath. Mutually exclusive — validated in connector.)
|
|
47
|
+
- Kerberos: `kerberosSpn?` (e.g. `HTTP@host.domain`), `kerberosService?` (default `HTTP`).
|
|
48
|
+
- `src/token/ITokenResult.ts`: no shape change needed — kerberos uses existing `tokenType: 'opaque'`. (Optional: add `'kerberos'` to the `tokenType` union for clarity; not required.)
|
|
49
|
+
- New interface `src/auth/ICertificateMaterialLoader.ts`:
|
|
50
|
+
```ts
|
|
51
|
+
export interface ICertificateMaterial { cert?: Buffer|string; key?: Buffer|string; pfx?: Buffer; passphrase?: string; }
|
|
52
|
+
export interface ICertificateMaterialLoader { load(config: ISapConfig): Promise<ICertificateMaterial>; }
|
|
53
|
+
```
|
|
54
|
+
- Export new symbols from `src/index.ts`.
|
|
55
|
+
|
|
56
|
+
### 3.2 `@mcp-abap-adt/connection` (`~/prj/mcp-abap-connection`) — the connector, heaviest changes
|
|
57
|
+
|
|
58
|
+
- `src/connection/AbstractAbapConnection.ts`:
|
|
59
|
+
- In `getAxiosInstance()` (currently builds `new Agent({ rejectUnauthorized })`), add a protected hook:
|
|
60
|
+
`protected getHttpsAgentOptions(): https.AgentOptions { return {}; }`
|
|
61
|
+
and merge it into the Agent options. **Important:** the Agent is currently cached on first build; certificate material must be available before the first request (it is — loaded in the cert connection's `connect()`/constructor). Keep `rejectUnauthorized` behavior intact.
|
|
62
|
+
- New `src/connection/CertificateAbapConnection.ts` (extends `AbstractAbapConnection`):
|
|
63
|
+
- `validateConfig`: requires `connectionType !== 'rfc'`; requires either (`certPath`+`certKeyPath`) or `certPfxPath`; rejects having both PEM and PFX.
|
|
64
|
+
- Constructor takes an injected `ICertificateMaterialLoader` (default: a file-based impl). `connect()` loads material, then proceeds with normal CSRF fetch.
|
|
65
|
+
- `getHttpsAgentOptions()` returns `{ cert, key, pfx, passphrase }`.
|
|
66
|
+
- `buildAuthorizationHeader()` returns `''` (no Authorization header; mTLS identifies the user).
|
|
67
|
+
- New `src/connection/KerberosAbapConnection.ts` (extends `AbstractAbapConnection`):
|
|
68
|
+
- **Self-contained — no broker, no `ITokenRefresher`, no provider.** Generates the SPNEGO token locally via the connection-local wrapper (below), using the resolved SPN.
|
|
69
|
+
- `connect()` generates the Negotiate token, sends it on the first request, captures the SAP session cookie via the existing cookie machinery; subsequent requests reuse the cookie.
|
|
70
|
+
- `buildAuthorizationHeader()` → `Negotiate ${token}` while no session cookie yet; `''` once a cookie exists.
|
|
71
|
+
- `validateConfig`: requires `connectionType !== 'rfc'`; requires resolvable SPN (`kerberosSpn` or derive `HTTP@<host>` from URL).
|
|
72
|
+
- New `src/auth/FileCertificateMaterialLoader.ts`: reads PEM/PFX from disk → `ICertificateMaterial`. Pure I/O, mockable.
|
|
73
|
+
- New `src/auth/kerberosSpnego.ts`: thin wrapper over the optional `kerberos` npm package (`initializeClient` / `step`), **lazy `import()`**; declared in this package's `optionalDependencies`. The single native, mockable seam. (Lives here, not in auth-providers, because `connection` does not depend on `auth-providers`.)
|
|
74
|
+
- `src/connection/connectionFactory.ts`: add cases:
|
|
75
|
+
```ts
|
|
76
|
+
case 'certificate': return new CertificateAbapConnection(config, logger, sessionId, options?.certLoader);
|
|
77
|
+
case 'kerberos': return new KerberosAbapConnection(config, logger, sessionId);
|
|
78
|
+
```
|
|
79
|
+
Keep the existing `connectionType === 'rfc'` early-return guard (rfc wins) — but add validation so cert/kerberos + rfc throws a clear error rather than silently doing RFC.
|
|
80
|
+
- `src/config/sapConfig.ts`: extend `sapConfigSignature()` to include cert paths / SPN (so connection is recreated when these change). Never log key/passphrase contents.
|
|
81
|
+
|
|
82
|
+
### 3.3 NOT touched: `auth-providers` and `auth-broker`
|
|
83
|
+
|
|
84
|
+
Certificate and Kerberos bypass both. The broker is only for OAuth-style authorization + browser-callback interception; cert/kerberos are non-interactive and connection-level. **Do not add a `KerberosProvider` to auth-providers, do not modify `AuthBroker`, do not widen the broker's `IConnectionConfig.authType`** — that union is the broker's surface and stays `'basic' | 'jwt' | 'saml'`.
|
|
85
|
+
|
|
86
|
+
### 3.4 `mcp-abap-adt` (server, this repo)
|
|
87
|
+
|
|
88
|
+
- `src/lib/config.ts` (lines ~59-75) and `src/lib/utils.ts` (duplicate parser ~1892-1900): extend `SAP_AUTH_TYPE` acceptance to include `'certificate'` and `'kerberos'`. **De-dup opportunity:** these two parsers are copies — extract one shared `parseAuthType()` (recommended while here).
|
|
89
|
+
- Read new env into the assembled `SapConfig`: `SAP_CERT_PATH`, `SAP_CERT_KEY_PATH`, `SAP_CERT_PFX_PATH`, `SAP_CERT_PASSPHRASE`, `SAP_KERBEROS_SPN`, `SAP_KERBEROS_SERVICE`. Document in the help text (~line 1337).
|
|
90
|
+
- **Connection creation path:** find where the server creates an `AbapConnection` for non-broker auth (basic/RFC today) — cert/kerberos follow that same direct `createAbapConnection(...)` path, NOT the broker/`brokerFactory` path. Verify in code during Phase 3; do NOT route cert/kerberos through `brokerFactory`/`IBrokerSessionConfig`.
|
|
91
|
+
- Tool `available_in`: cert/kerberos are connection concerns, not tool capabilities — no tool-level change; but verify nothing assumes `authType ∈ {basic,jwt,saml}`.
|
|
92
|
+
|
|
93
|
+
## 4. Configuration surface (summary)
|
|
94
|
+
|
|
95
|
+
`.env` (server-driven, on-prem HTTP):
|
|
96
|
+
```
|
|
97
|
+
SAP_AUTH_TYPE=certificate
|
|
98
|
+
SAP_CERT_PATH=/path/client.crt # PEM
|
|
99
|
+
SAP_CERT_KEY_PATH=/path/client.key # PEM
|
|
100
|
+
# or:
|
|
101
|
+
SAP_CERT_PFX_PATH=/path/client.pfx # PKCS#12
|
|
102
|
+
SAP_CERT_PASSPHRASE=... # optional
|
|
103
|
+
```
|
|
104
|
+
```
|
|
105
|
+
SAP_AUTH_TYPE=kerberos
|
|
106
|
+
SAP_KERBEROS_SPN=HTTP@sap-host.corp # optional; derived from SAP_URL if absent
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## 5. Security rules
|
|
110
|
+
|
|
111
|
+
- Never log private-key bytes, PFX bytes, passphrase, or Negotiate tokens. Safe to log: cert subject/CN, cert path (not contents), SPN, `tokenType`.
|
|
112
|
+
- `sapConfigSignature()` must not embed secret material — use presence flags / hashes, mirroring how it previews tokens today.
|
|
113
|
+
- Reject NTLM: if the server's `WWW-Authenticate` offers only `NTLM` (token begins `TlRMTVNTUAA...`), fail with a clear error rather than negotiating.
|
|
114
|
+
|
|
115
|
+
## 6. Test plan
|
|
116
|
+
|
|
117
|
+
Per repo, unit-first (mock the native/IO seams):
|
|
118
|
+
|
|
119
|
+
- **interfaces**: type-level only (compile).
|
|
120
|
+
- **connection**:
|
|
121
|
+
- `CertificateAbapConnection`: inject a fake `ICertificateMaterialLoader`; assert `getHttpsAgentOptions()` carries cert/key/pfx; assert no Authorization header; assert PEM-vs-PFX validation and rfc-conflict errors.
|
|
122
|
+
- `KerberosAbapConnection`: mock the connection-local `kerberosSpnego` wrapper; assert `Authorization: Negotiate <token>` on first request and `''` after a cookie exists; assert cookie capture+reuse; assert rfc-conflict error. No real KDC.
|
|
123
|
+
- `connectionFactory`: new cases route correctly; cert/kerberos + rfc throws.
|
|
124
|
+
- **server**: `SAP_AUTH_TYPE=certificate|kerberos` parsed (shared `parseAuthType`); cert/kerberos env fields land in the assembled `SapConfig`; connection created via the direct `createAbapConnection` path (not broker).
|
|
125
|
+
- **Integration (live SAP, gated):** one cert smoke + one kerberos smoke against an on-prem system that supports them. Follow CLAUDE.md soft-mode strategy; do not block CI on secrets (see integration-test-env-gates approach).
|
|
126
|
+
|
|
127
|
+
## 7. Release order (cross-package)
|
|
128
|
+
|
|
129
|
+
Bottom-up. **The user publishes each package — the agent never runs `npm publish`.** Consumers import published npm versions (not local links), so each step is hard-gated: implement → commit → PR/merge → user publishes → bump consumer to the confirmed version → next step (follow the cross-package-fix-cycle discipline):
|
|
130
|
+
|
|
131
|
+
1. `interfaces` — union + fields + `ICertificateMaterialLoader`. User publishes, bump everywhere.
|
|
132
|
+
2. `connection` — connection classes + agent hook + cert loader + `kerberosSpnego` (optionalDep) + factory + signature. User publishes.
|
|
133
|
+
3. `mcp-abap-adt` (server) — `parseAuthType` + env→`SapConfig` + direct `createAbapConnection` wiring + docs. Bump deps to the published versions.
|
|
134
|
+
|
|
135
|
+
(`auth-providers` and `auth-broker` are not in the chain — not touched.) Each step gets its own worktree in its repo (per project workflow: worktrees on all changed code repos; spec stays only here).
|
|
136
|
+
|
|
137
|
+
## 8. Risks & assumptions
|
|
138
|
+
|
|
139
|
+
- **A1 — single-leg Negotiate.** Assumes SAP accepts a one-shot AP-REQ then issues a session cookie (typical for Kerberos). If a system demands mutual-auth continuation (`WWW-Authenticate: Negotiate <challenge>` round-trips), the single-token approach does not cover it; would need a continuation hook. **Accepted for v1** (user-confirmed); validate on a live system before claiming kerberos done.
|
|
140
|
+
- **A2 — native build.** `kerberos` npm compiles native bindings (needs GSSAPI dev libs on Linux / build tools on Windows). Mitigated by `optionalDependencies` + lazy import so non-kerberos installs never touch it.
|
|
141
|
+
- **A3 — TGT availability.** Cross-platform kerberos needs a valid TGT in the OS credential cache (`kinit`) or a keytab. Document prerequisite; not auto-provisioned.
|
|
142
|
+
- **A4 — Agent caching.** `getAxiosInstance()` caches the Agent; ensure cert material is loaded before the first request (it is, in `connect()`), else the cached Agent lacks the client cert.
|
|
143
|
+
- **A5 — duplicate auth parser.** `config.ts` and `utils.ts` both parse `SAP_AUTH_TYPE`; both must change. Optional de-dup flagged in §3.5.
|
|
144
|
+
|
|
145
|
+
## 9. Decisions (resolved)
|
|
146
|
+
|
|
147
|
+
1. **PEM and PFX both supported** in v1. (user-confirmed)
|
|
148
|
+
2. **Single-leg Negotiate accepted** for v1; no mutual-auth continuation. (user-confirmed)
|
|
149
|
+
3. **cert and kerberos both bypass the broker and auth-providers** — connection-layer only. (user-confirmed)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-abap-adt/core",
|
|
3
3
|
"mcpName": "io.github.fr0ster/mcp-abap-adt",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.9.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -140,9 +140,9 @@
|
|
|
140
140
|
"@mcp-abap-adt/auth-broker": "^1.0.5",
|
|
141
141
|
"@mcp-abap-adt/auth-providers": "^1.0.5",
|
|
142
142
|
"@mcp-abap-adt/auth-stores": "^1.0.4",
|
|
143
|
-
"@mcp-abap-adt/connection": "^1.
|
|
143
|
+
"@mcp-abap-adt/connection": "^1.9.0",
|
|
144
144
|
"@mcp-abap-adt/header-validator": "^0.1.8",
|
|
145
|
-
"@mcp-abap-adt/interfaces": "^7.
|
|
145
|
+
"@mcp-abap-adt/interfaces": "^7.2.0",
|
|
146
146
|
"@mcp-abap-adt/logger": "^0.1.4",
|
|
147
147
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
148
148
|
"axios": "^1.14.0",
|