toga-ai 1.0.670 → 1.0.671

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.
@@ -6,3 +6,4 @@
6
6
  | [SAML Downstream Integration Contract](features/downstream-integration-contract.md) | The contract a **downstream TOGa app** implements to authenticate users through the SAML gateway (`saml.togahub.com`). | saml/Controller/Index.php, _underscore/Model/Core/ClientAuthentication.php, _underscore/Model/True/ClientAuthentication.php |
7
7
  | [Rate SAML User Provisioning](features/rate-user-provisioning.md) | When a Rate user authenticates via SSO, `_Model_Rate_ClientAuthentication::getAuthenticatedSsoUser()` is called by the saml gateway. | _underscore/Model/Rate/ClientAuthentication.php, _underscore/Model/Rate/User.php, _underscore/Model/Rate/Customer.php, _underscore/Model/Rate/Contact.php |
8
8
  | [Onboarding a New SSO Client with Just-In-Time User Provisioning](workflows/onboarding-a-new-sso-client.md) | The repeatable procedure for adding a new client to the 2.0 `saml` gateway when that client's users do **not** pre-exist in our database and must be created on | saml/Controller/Index.php, _underscore/Model/Core/ClientAuthentication.php, _underscore/Model/Rate/ClientAuthentication.php, _underscore/Database.php |
9
+ | [Rotating the SAML SP Certificate](workflows/rotating-the-saml-sp-certificate.md) | The repeatable procedure for replacing the TOGa **SAML Service Provider (SP) credential** — the X.509 cert + private key at `_underscore/Assets/ssl/togahub_com. | _underscore/Assets/ssl/togahub_com.crt, _underscore/Assets/ssl/togahub_private_key.key, _underscore/Model/Core/ClientAuthentication.php, saml/Controller/Index.php |
@@ -0,0 +1,109 @@
1
+ ---
2
+ title: Rotating the SAML SP Certificate
3
+ framework: "2.0"
4
+ repo: saml
5
+ project: SAML SSO Gateway
6
+ client: shared
7
+ type: workflow
8
+ status: active
9
+ updated: 2026-08-27
10
+ owners: ["jcardinal"]
11
+ files:
12
+ - _underscore/Assets/ssl/togahub_com.crt
13
+ - _underscore/Assets/ssl/togahub_private_key.key
14
+ - _underscore/Model/Core/ClientAuthentication.php
15
+ - saml/Controller/Index.php
16
+ related:
17
+ - 2.0/apps/saml/architecture.md
18
+ - 2.0/apps/saml/workflows/onboarding-a-new-sso-client.md
19
+ ---
20
+
21
+ ## Summary
22
+
23
+ The repeatable procedure for replacing the TOGa **SAML Service Provider (SP) credential** — the
24
+ X.509 cert + private key at `_underscore/Assets/ssl/togahub_com.crt` and
25
+ `_underscore/Assets/ssl/togahub_private_key.key`. This credential is the SP's own identity, used
26
+ to **sign outgoing AuthnRequests** and to **decrypt inbound assertions**. It is a bilateral,
27
+ partner-pinned trust artifact, **not** the TLS cert that terminates browser HTTPS. There was no
28
+ rotation runbook before this (git shows two prior undocumented swaps); this closes that gap.
29
+
30
+ For *why* a self-signed, long-lived cert is the correct choice here (rather than a public-CA TLS
31
+ cert), see the SSL certificate trust-model strategy standard.
32
+
33
+ ## How the SP credential is used
34
+
35
+ - **Private key — signs outgoing SP AuthnRequests.** `_Model_Core_ClientAuthentication`
36
+ (`_underscore/Model/Core/ClientAuthentication.php`) points its `PATH_TO_PRIVATE_KEY` constant
37
+ at `_underscore/Assets/ssl/togahub_private_key.key` and signs with XMLSecLibs `RSA_SHA256`
38
+ (around lines 11 / 95 / 107).
39
+ - **Public cert — published in SP metadata and used to decrypt assertions.** The `saml` repo's
40
+ `Controller/Index.php` uses the cert for assertion decryption; the `/meta` route publishes it
41
+ in SP metadata via `file_get_contents` read fresh on each request (no server-side cache).
42
+ - **IdPs cache metadata up to 7 days** (`cacheDuration PT604800S`), so a cert change is not
43
+ guaranteed to be picked up by every IdP immediately after deploy.
44
+
45
+ ## Current credential (as of 2026-08-27, staged — cutover pending)
46
+
47
+ A dedicated **self-signed** replacement was generated to decouple the SP credential from the
48
+ short-lived DigiCert/Thawte TLS wildcard that had been reused as the SP cert (see Background):
49
+
50
+ - Self-signed X.509, RSA 2048, SHA-256.
51
+ - Subject/Issuer: `C=US, ST=Illinois, L=Naperville, O=TOGA Technology, Inc., CN=togahub.com`
52
+ (reflects the new company name TOGA Technology, Inc. / Naperville, IL — formerly Agilant
53
+ Solutions, Inc.). CN only, **no SANs** — SANs are meaningless for bilateral SAML/AS2 trust.
54
+ - Validity: **2026-08-27 → 2036-08-27** (10 years). Capped at 10y because RSA 2048 is
55
+ NIST-assured only to ~2030; a longer term would call for RSA 4096, and client compatibility
56
+ with 4096 is unconfirmed.
57
+ - SHA-256 fingerprint:
58
+ `0E:1E:9E:11:35:B9:74:79:6F:07:2B:1F:E7:05:B8:B6:E9:07:00:0B:9E:A2:36:94:04:F6:AC:65:AC:B0:03:78`
59
+
60
+ ### Where the material lives (never paste the key)
61
+
62
+ - **AWS Secrets Manager**, account **654654170868**, region **us-east-1**.
63
+ - Secret name: **`toga/ssl/togahub_com-selfsigned-2036`**.
64
+ - ARN: `arn:aws:secretsmanager:us-east-1:654654170868:secret:toga/ssl/togahub_com-selfsigned-2036-S2r3SR`.
65
+ - JSON keys: `{certificate, privateKey}`. Retrieve the private key from here at cutover — it is
66
+ **not** stored anywhere else and must never be committed or pasted into chat/docs.
67
+ - The public cert only was staged locally at `C:\TEMP\toga-ssl-2026\togahub_com.crt`; the local
68
+ private key was deleted.
69
+
70
+ ## Cutover procedure
71
+
72
+ 1. **PRE-CUTOVER SAFETY CHECK — confirm this cert is not serving live TLS.** Before replacing a
73
+ real CA cert with a self-signed one, verify the `.crt`/`.key` at `_underscore/Assets/ssl/` is
74
+ **not** also terminating browser/API TLS anywhere (check the `saml` repo + its EB/Apache
75
+ config). TLS is normally ACM-terminated at the ALB, so this repo file should only be the
76
+ SAML/AS2 credential — but verify against the checked-out `saml` repo first.
77
+ 2. **Distribute the new public cert to every pinning partner** (SAML IdPs, AS2 partners, any
78
+ PunchOut buyer that pins our leaf) and let them import it. Include the SHA-256 fingerprint
79
+ above as the verification line.
80
+ 3. **Coordinate a cutover date/time** with those partners.
81
+ 4. **Replace both files in `_underscore` on the `_production` branch** — via a feature branch +
82
+ PR, **never a direct commit to `_production`**. No code change is needed: the path constants
83
+ already point at these filenames.
84
+ 5. **Redeploy `saml` after the `_underscore` merge.** `saml` pulls `_underscore` from
85
+ `_production` at EB build time (`.ebextensions/git.php` + prebuild hook), so a saml-only
86
+ deploy will **not** pick up the new cert. Deploy target: `saml-production` EB env, us-east-1,
87
+ DNS `saml.togahub.com`.
88
+ 6. **Deploy the cert+key to the other bilateral services** that use the same SP credential —
89
+ AS2 (AWS Transfer Family) and any other pinned endpoint — importing both cert and key.
90
+
91
+ ## Background — why the change
92
+
93
+ The old `_underscore/Assets/ssl/togahub_com.crt` was a **reused DigiCert/Thawte multi-domain
94
+ wildcard TLS cert** (issuer "Thawte TLS RSA CA G1"; SANs for togahub.com, togacommerce.com,
95
+ togadesk.com, togaretail.com, togasupply.com, togaview.com, togaiq.com plus `*.` of each; RSA
96
+ 2048; validity Mar 2 2026 → Sep 16 2026, ~6.5 months). Reusing a short-lived public-CA TLS cert
97
+ as the SAML SP credential accidentally coupled SAML to a ~6-month renewal treadmill and forced
98
+ every pinning partner to reinstall on each renewal. The dedicated self-signed 10-year cert
99
+ **decouples the SP credential from TLS renewals** — that is the whole point of the change.
100
+
101
+ ## Change history
102
+ - 2026-08-27 — Created while replacing the SAML SP credential. Documented the SP cert's dual use
103
+ (signing AuthnRequests / decrypting assertions), the new self-signed 10-year cert identity and
104
+ its AWS Secrets Manager location, the pre-cutover TLS-usage safety check, and the
105
+ `_underscore`-then-`saml` cutover ordering. Discovered the prior cert was a reused short-lived
106
+ DigiCert wildcard TLS cert, which is the reason for the switch. Cutover itself still pending.
107
+ (jcardinal)
108
+ </content>
109
+ </invoke>
@@ -0,0 +1,82 @@
1
+ ---
2
+ title: SSL Certificate Trust-Model Strategy
3
+ framework: "2.0"
4
+ project: _Underscore
5
+ client: shared
6
+ type: standard
7
+ status: active
8
+ updated: 2026-08-27
9
+ owners: [jcardinal]
10
+ files: []
11
+ related:
12
+ - ../apps/saml/workflows/rotating-the-saml-sp-certificate.md
13
+ - ../apps/saml/architecture.md
14
+ ---
15
+
16
+ ## Summary
17
+
18
+ Which kind of SSL/TLS certificate to use is decided by the **trust model** of the endpoint, not
19
+ by habit. Pick wrong and you land on a renewal treadmill; pick right and renewals become either
20
+ invisible or irrelevant. This standard is platform-wide (1.0, 2.0, standalone, and pure-AWS
21
+ infra). It was established while replacing the 2.0 SAML SP credential — see the
22
+ [SAML SP certificate rotation runbook](../apps/saml/workflows/rotating-the-saml-sp-certificate.md).
23
+
24
+ **Critical rule:** if a partner installs/pins OUR specific cert, use a **self-signed, long-lived**
25
+ cert. If AWS terminates the TLS for browsers/generic clients, use **ACM public, auto-renewing**.
26
+ Never reuse a public-CA TLS cert as a pinned bilateral credential.
27
+
28
+ ## The decision
29
+
30
+ ### 1. Bilateral / pinned trust → self-signed, long-lived
31
+ The partner installs and pins our specific certificate: SAML SP credential, AS2 (AWS Transfer
32
+ Family), PunchOut endpoints a buyer pins. Use a **self-signed** cert with a multi-year validity
33
+ (we generate 10-year). Distribute the public cert to the partner; import cert + key into the
34
+ service. Because trust is by pinning, no public CA is involved and validity can be long.
35
+
36
+ ### 2. Standard HTTPS, AWS-terminated → ACM public, non-exportable, auto-renewing
37
+ Browsers / generic clients reach the endpoint through an ALB, CloudFront, or API Gateway that AWS
38
+ terminates. Use an **ACM public certificate** (non-exportable, auto-renewing). Distribute nothing;
39
+ renewal is invisible.
40
+
41
+ ### 3. Standard HTTPS, NOT AWS-terminated → ACM exportable, or move behind an ALB
42
+ A server terminates its own TLS (e.g. the legacy Vision box). Options: an **ACM *exportable*
43
+ public cert** (a real 2025 AWS feature) — but still ~13-month validity, so you must redeploy on
44
+ every renewal — OR move the endpoint behind an ALB to get free auto-renew (option 2).
45
+
46
+ ## Why long-lived ⇒ self-signed
47
+
48
+ **Every publicly-trusted cert, exportable or not, is capped at ~398 days** by the CA/Browser
49
+ Forum, dropping toward ~47 days by 2029. Only **self-signed / private-CA** certs can be
50
+ multi-year. So "long-lived AND distributable" necessarily means self-signed (or AWS Private CA at
51
+ ~$400/mo — rejected here as overkill).
52
+
53
+ The pain of "shrinking public-cert validity" is really a **distribution problem**: automate
54
+ distribution via ACM and it disappears; a partner who pins the leaf breaks on every rotation.
55
+ That is exactly why bilateral, pinned credentials should be self-signed and long-lived — and why
56
+ reusing a short-lived public-CA TLS cert as a pinned SP/AS2 credential (as we accidentally did for
57
+ SAML) couples an otherwise stable credential to a ~6-month treadmill.
58
+
59
+ ## Key sizing
60
+
61
+ Self-signed long-lived certs use RSA 2048 / SHA-256 with validity capped at ~10 years, because
62
+ RSA 2048 is NIST-assured only to ~2030. A longer term would want RSA 4096, but partner
63
+ compatibility with 4096 is often unconfirmed — verify before choosing it.
64
+
65
+ ## Worked example — Vision / Canon cXML PunchOut (a split-trust endpoint)
66
+
67
+ The Vision cXML PunchOut endpoint (`vision.asisystem.com`, a separate domain/cert from
68
+ togahub.com) is a single cert serving **two legs with different trust models**, which is why its
69
+ renewals are painful:
70
+
71
+ - **Server-to-server cXML leg** — auth is a `<Credential>` **SharedSecret** (localVerifyIdentity),
72
+ not a client cert; our cert there is only the endpoint's TLS wrapper. The buyer reinstalling our
73
+ cert on every renewal indicates they **pin our leaf** — effectively bilateral trust → a
74
+ self-signed long-lived cert fits.
75
+ - **PunchOut portal StartPage** (`punchoutSetupResponseUrlPrefix`) is a real **browser** session →
76
+ needs a public-CA cert (option 2).
77
+
78
+ Bundling both on one cert is the root of the pain. The fix is to **split** them: ACM for the
79
+ browser portal, self-signed for the pinned cXML endpoint. StartPage host is per-identity
80
+ configurable, so the split is feasible. Canon is slated to move from Vision to TOGa Commerce (2.0,
81
+ already ALB+ACM), which auto-solves the browser leg.
82
+ </content>
@@ -23,7 +23,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
23
23
  - **api2** (API) — 25 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
24
24
  - **dbchanges2** (Database Changes) _(framework core)_ — 13 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
25
25
  - **toga2-supply** (TOGa Supply) — 9 doc(s) → [2.0/apps/toga2-supply/INDEX.md](2.0/apps/toga2-supply/INDEX.md)
26
- - **saml** (SAML SSO Gateway) — 4 doc(s) → [2.0/apps/saml/INDEX.md](2.0/apps/saml/INDEX.md)
26
+ - **saml** (SAML SSO Gateway) — 5 doc(s) → [2.0/apps/saml/INDEX.md](2.0/apps/saml/INDEX.md)
27
27
  - **toga2-view** (TOGa View Frontend) — 12 doc(s) → [2.0/apps/toga2-view/INDEX.md](2.0/apps/toga2-view/INDEX.md)
28
28
  - **toga2-hub** (TOGa Hub) — 2 doc(s) → [2.0/apps/toga2-hub/INDEX.md](2.0/apps/toga2-hub/INDEX.md)
29
29
  - **talos** (TOGa IQ) — 7 doc(s) → [2.0/apps/talos/INDEX.md](2.0/apps/talos/INDEX.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.670",
3
+ "version": "1.0.671",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",