@simonsbs/keylore 1.0.0-rc4

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.
Files changed (81) hide show
  1. package/.env.example +64 -0
  2. package/LICENSE +176 -0
  3. package/NOTICE +5 -0
  4. package/README.md +424 -0
  5. package/bin/keylore-http.js +3 -0
  6. package/bin/keylore-stdio.js +3 -0
  7. package/data/auth-clients.json +54 -0
  8. package/data/catalog.json +53 -0
  9. package/data/policies.json +25 -0
  10. package/dist/adapters/adapter-registry.js +143 -0
  11. package/dist/adapters/aws-secrets-manager-adapter.js +99 -0
  12. package/dist/adapters/command-runner.js +17 -0
  13. package/dist/adapters/env-secret-adapter.js +42 -0
  14. package/dist/adapters/gcp-secret-manager-adapter.js +129 -0
  15. package/dist/adapters/local-secret-adapter.js +54 -0
  16. package/dist/adapters/onepassword-secret-adapter.js +83 -0
  17. package/dist/adapters/reference-utils.js +44 -0
  18. package/dist/adapters/types.js +1 -0
  19. package/dist/adapters/vault-secret-adapter.js +103 -0
  20. package/dist/app.js +132 -0
  21. package/dist/cli/args.js +51 -0
  22. package/dist/cli/run.js +483 -0
  23. package/dist/cli.js +18 -0
  24. package/dist/config.js +295 -0
  25. package/dist/domain/types.js +967 -0
  26. package/dist/http/admin-ui.js +3010 -0
  27. package/dist/http/server.js +1210 -0
  28. package/dist/index.js +40 -0
  29. package/dist/mcp/create-server.js +388 -0
  30. package/dist/mcp/stdio.js +7 -0
  31. package/dist/repositories/credential-repository.js +109 -0
  32. package/dist/repositories/interfaces.js +1 -0
  33. package/dist/repositories/json-file.js +20 -0
  34. package/dist/repositories/pg-access-token-repository.js +118 -0
  35. package/dist/repositories/pg-approval-repository.js +157 -0
  36. package/dist/repositories/pg-audit-log.js +62 -0
  37. package/dist/repositories/pg-auth-client-repository.js +98 -0
  38. package/dist/repositories/pg-authorization-code-repository.js +95 -0
  39. package/dist/repositories/pg-break-glass-repository.js +174 -0
  40. package/dist/repositories/pg-credential-repository.js +163 -0
  41. package/dist/repositories/pg-oauth-client-assertion-repository.js +25 -0
  42. package/dist/repositories/pg-policy-repository.js +62 -0
  43. package/dist/repositories/pg-refresh-token-repository.js +125 -0
  44. package/dist/repositories/pg-rotation-run-repository.js +127 -0
  45. package/dist/repositories/pg-tenant-repository.js +56 -0
  46. package/dist/repositories/policy-repository.js +24 -0
  47. package/dist/runtime/sandbox-runner.js +114 -0
  48. package/dist/services/access-fingerprint.js +13 -0
  49. package/dist/services/approval-service.js +148 -0
  50. package/dist/services/audit-log.js +38 -0
  51. package/dist/services/auth-context.js +43 -0
  52. package/dist/services/auth-secrets.js +14 -0
  53. package/dist/services/auth-service.js +784 -0
  54. package/dist/services/backup-service.js +610 -0
  55. package/dist/services/break-glass-service.js +207 -0
  56. package/dist/services/broker-service.js +557 -0
  57. package/dist/services/core-mode-service.js +154 -0
  58. package/dist/services/egress-policy.js +119 -0
  59. package/dist/services/local-secret-store.js +119 -0
  60. package/dist/services/maintenance-service.js +99 -0
  61. package/dist/services/notification-service.js +83 -0
  62. package/dist/services/policy-engine.js +85 -0
  63. package/dist/services/rate-limit-service.js +80 -0
  64. package/dist/services/rotation-service.js +271 -0
  65. package/dist/services/telemetry.js +149 -0
  66. package/dist/services/tenant-service.js +127 -0
  67. package/dist/services/trace-export-service.js +126 -0
  68. package/dist/services/trace-service.js +87 -0
  69. package/dist/storage/bootstrap.js +68 -0
  70. package/dist/storage/database.js +39 -0
  71. package/dist/storage/in-memory-database.js +40 -0
  72. package/dist/storage/migrations.js +27 -0
  73. package/migrations/001_init.sql +49 -0
  74. package/migrations/002_phase2_auth.sql +53 -0
  75. package/migrations/003_v05_operations.sql +9 -0
  76. package/migrations/004_v07_security.sql +28 -0
  77. package/migrations/005_v08_reviews.sql +11 -0
  78. package/migrations/006_v09_auth_trace_rotation.sql +51 -0
  79. package/migrations/007_v010_multi_tenant.sql +32 -0
  80. package/migrations/008_v011_auth_tenant_ops.sql +95 -0
  81. package/package.json +78 -0
package/.env.example ADDED
@@ -0,0 +1,64 @@
1
+ KEYLORE_DATABASE_URL=postgresql://keylore:keylore@127.0.0.1:5432/keylore
2
+ KEYLORE_DATABASE_POOL_MAX=10
3
+ KEYLORE_AUTH_CLIENTS_FILE=auth-clients.json
4
+ KEYLORE_LOCAL_SECRETS_FILE=local-secrets.enc.json
5
+ KEYLORE_LOCAL_SECRETS_KEY_FILE=local-secrets.key
6
+ KEYLORE_HTTP_HOST=127.0.0.1
7
+ KEYLORE_HTTP_PORT=8787
8
+ KEYLORE_PUBLIC_BASE_URL=http://127.0.0.1:8787
9
+ KEYLORE_OAUTH_ISSUER_URL=http://127.0.0.1:8787/oauth
10
+ KEYLORE_DEFAULT_PRINCIPAL=local-operator
11
+ KEYLORE_ENVIRONMENT=development
12
+ KEYLORE_LOG_LEVEL=info
13
+ KEYLORE_BOOTSTRAP_FROM_FILES=true
14
+ KEYLORE_MAX_REQUEST_BYTES=131072
15
+ KEYLORE_OUTBOUND_TIMEOUT_MS=10000
16
+ KEYLORE_MAX_RESPONSE_BYTES=32768
17
+ KEYLORE_RATE_LIMIT_WINDOW_MS=60000
18
+ KEYLORE_RATE_LIMIT_MAX_REQUESTS=120
19
+ KEYLORE_MAINTENANCE_ENABLED=true
20
+ KEYLORE_MAINTENANCE_INTERVAL_MS=60000
21
+ KEYLORE_ACCESS_TOKEN_TTL_SECONDS=3600
22
+ KEYLORE_AUTHORIZATION_CODE_TTL_SECONDS=300
23
+ KEYLORE_REFRESH_TOKEN_TTL_SECONDS=2592000
24
+ KEYLORE_APPROVAL_TTL_SECONDS=1800
25
+ KEYLORE_APPROVAL_REVIEW_QUORUM=1
26
+ KEYLORE_BREAKGLASS_MAX_DURATION_SECONDS=900
27
+ KEYLORE_BREAKGLASS_REVIEW_QUORUM=1
28
+ KEYLORE_VAULT_ADDR=
29
+ KEYLORE_VAULT_TOKEN=
30
+ KEYLORE_VAULT_NAMESPACE=
31
+ KEYLORE_OP_BIN=op
32
+ KEYLORE_AWS_BIN=aws
33
+ KEYLORE_GCLOUD_BIN=gcloud
34
+ KEYLORE_EGRESS_ALLOW_PRIVATE_IPS=false
35
+ KEYLORE_EGRESS_ALLOWED_HOSTS=
36
+ KEYLORE_EGRESS_ALLOWED_HTTPS_PORTS=443
37
+ KEYLORE_SANDBOX_INJECTION_ENABLED=false
38
+ KEYLORE_SANDBOX_COMMAND_ALLOWLIST=
39
+ KEYLORE_SANDBOX_ENV_ALLOWLIST=
40
+ KEYLORE_SANDBOX_DEFAULT_TIMEOUT_MS=5000
41
+ KEYLORE_SANDBOX_MAX_OUTPUT_BYTES=16384
42
+ KEYLORE_ADAPTER_MAX_ATTEMPTS=2
43
+ KEYLORE_ADAPTER_RETRY_DELAY_MS=250
44
+ KEYLORE_ADAPTER_CIRCUIT_BREAKER_THRESHOLD=3
45
+ KEYLORE_ADAPTER_CIRCUIT_BREAKER_COOLDOWN_MS=60000
46
+ KEYLORE_NOTIFICATION_WEBHOOK_URL=
47
+ KEYLORE_NOTIFICATION_SIGNING_SECRET=
48
+ KEYLORE_NOTIFICATION_TIMEOUT_MS=5000
49
+ KEYLORE_TRACE_CAPTURE_ENABLED=true
50
+ KEYLORE_TRACE_RECENT_SPAN_LIMIT=500
51
+ KEYLORE_TRACE_EXPORT_URL=
52
+ KEYLORE_TRACE_EXPORT_AUTH_HEADER=
53
+ KEYLORE_TRACE_EXPORT_BATCH_SIZE=20
54
+ KEYLORE_TRACE_EXPORT_INTERVAL_MS=1000
55
+ KEYLORE_TRACE_EXPORT_TIMEOUT_MS=5000
56
+ KEYLORE_ROTATION_PLANNING_HORIZON_DAYS=14
57
+
58
+ # Demo credentials. These are references only; KeyLore never stores secret values in the catalogue.
59
+ KEYLORE_SECRET_GITHUB_READONLY=
60
+ KEYLORE_SECRET_NPM_READONLY=
61
+
62
+ # Bootstrap OAuth clients. Required when bootstrapping auth clients from data/auth-clients.json.
63
+ KEYLORE_BOOTSTRAP_ADMIN_CLIENT_SECRET=
64
+ KEYLORE_BOOTSTRAP_CONSUMER_CLIENT_SECRET=
package/LICENSE ADDED
@@ -0,0 +1,176 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
package/NOTICE ADDED
@@ -0,0 +1,5 @@
1
+ KeyLore
2
+ Copyright 2026 Simon
3
+
4
+ This product includes third-party open source software distributed under
5
+ their own licenses. Dependency metadata is captured in `package-lock.json`.
package/README.md ADDED
@@ -0,0 +1,424 @@
1
+ # KeyLore
2
+
3
+ KeyLore is a credential broker and searchable credential catalogue for MCP clients such as Codex CLI, Claude Code, and other Model Context Protocol toolchains.
4
+
5
+ The design goal comes directly from the local `KeyLore.md` production spec used to bootstrap this repository: let agents discover and use the right credential metadata without ever putting secret values into model context, prompts, logs, or tool results.
6
+
7
+ ## Status
8
+
9
+ This repository is incubating privately today, but it is structured to be published as open source without a cleanup pass. The repo already includes:
10
+
11
+ - an Apache-2.0 project license and `NOTICE`
12
+ - contributor and security policies
13
+ - CI, container packaging, and deployment examples
14
+ - architecture, API, threat model, and roadmap docs
15
+ - conformance and tenant-operations guides
16
+ - compatibility contract and release-hardening guides
17
+ - admin UI guide
18
+ - release checklist
19
+
20
+ ## What is implemented now
21
+
22
+ - MCP server for `stdio` and Streamable HTTP
23
+ - metadata-only catalogue search and retrieval tools
24
+ - default-deny policy engine with domain and operation constraints
25
+ - PostgreSQL-backed catalogue, policy, and audit persistence with startup migrations
26
+ - OAuth-style client credentials token issuance for remote HTTP and MCP access
27
+ - PKCE-bound `authorization_code` plus rotating `refresh_token` support for interactive public or confidential clients
28
+ - protected-resource metadata for REST and MCP surfaces
29
+ - identity-aware policy evaluation with role-aware rule matching
30
+ - approval-required policy outcomes with review endpoints and CLI support
31
+ - multi-review approval and break-glass quorums with duplicate-review protection
32
+ - RBAC separation for admin, auth admin, operator, maintenance, backup, break-glass, auditor, approver, and consumer clients
33
+ - policy simulation and non-executing dry-run access evaluation
34
+ - auth-client lifecycle APIs with secret rotation and status control
35
+ - token listing and explicit token revocation APIs
36
+ - pluggable secret adapters for environment bindings, Vault, 1Password, AWS Secrets Manager, and GCP Secret Manager
37
+ - catalog reporting for rotation and expiry visibility
38
+ - sandboxed injection mode for tightly allowlisted compatibility commands
39
+ - constrained proxy execution for `http.get` and `http.post`
40
+ - HTTP admin/API surface for catalogue search, access requests, approvals, audit reads, adapter health, runtime injection, and auth-client inspection
41
+ - local admin CLI for catalogue, reporting, access evaluation, runtime injection, approvals, auth-client, maintenance, and backup operations
42
+ - request-size limits, database-backed rate limiting, background maintenance cleanup, outbound timeouts, and response-size caps
43
+ - Prometheus-style `/metrics` telemetry and request correlation headers for operational visibility
44
+ - audited break-glass request, approval, revoke, and emergency-use flow
45
+ - delegated backup export, inspect, and restore API endpoints for self-hosted operators
46
+ - egress policy blocks private, loopback, and link-local upstream targets unless explicitly allowed
47
+ - sandbox env allowlisting for injected runtime execution
48
+ - signed notification webhooks for approval and break-glass lifecycle events
49
+ - request trace capture with `x-trace-id` propagation and recent-trace inspection
50
+ - optional external trace export with operator status and manual flush controls
51
+ - `private_key_jwt` OAuth client authentication with assertion replay protection
52
+ - persisted credential rotation workflows with plan, start, complete, and fail transitions
53
+ - tenant-aware partitioning for credentials, policies, auth clients, approvals, break-glass, audit events, tokens, rotation runs, and logical backups
54
+ - first-class tenant registry with tenant bootstrap workflows for auth-client seeding
55
+ - tenant-scoped backup export and restore isolation for delegated tenant operators
56
+ - explicit conformance suite for auth, tenancy, and backup boundary regressions
57
+ - frozen `v1.0.0-rc1` compatibility contract for OAuth, REST, and MCP tool names
58
+ - dedicated hardening suite for replay, tenant-isolation, and delegated-admin abuse paths
59
+ - minimal admin UI for operator login, tenants, auth clients, reviews, backups, audit, and system status
60
+ - Helm chart with dev, staging, and production values profiles
61
+ - HA-oriented Helm profile with pod disruption budget and spread controls
62
+ - tagged release workflow with SBOM generation, vulnerability scanning, keyless image signing, and Helm upgrade validation
63
+ - shipped Grafana dashboard and Prometheus alert rule examples
64
+
65
+ ## What is intentionally deferred
66
+
67
+ The full `KeyLore.md` specification is broader than a sane `v1.0.0-rc4` delivery. The main remaining work before `v1.0.0` is:
68
+
69
+ - public release polish and final operator documentation cleanup
70
+
71
+ Those items are tracked in [docs/roadmap.md](/home/simon/keylore/docs/roadmap.md) and mapped back to the spec in [docs/keylore-spec-map.md](/home/simon/keylore/docs/keylore-spec-map.md).
72
+
73
+ The active post-`v1.0.0-rc4` refocus is documented in [docs/core-mode-plan.md](/home/simon/keylore/docs/core-mode-plan.md): make the default user journey "add secret, add context, connect MCP, use it" and push broader operator features behind an advanced path.
74
+
75
+ The handoff from local core mode to advanced self-hosted mode is documented in [docs/production-handoff.md](/home/simon/keylore/docs/production-handoff.md).
76
+
77
+ ## Quick start
78
+
79
+ 1. Install dependencies:
80
+
81
+ ```bash
82
+ npm install
83
+ ```
84
+
85
+ 2. Start the zero-config local stack:
86
+
87
+ ```bash
88
+ npm run quickstart
89
+ ```
90
+
91
+ For a clean Linux VM install from npm instead of cloning the repo:
92
+
93
+ ```bash
94
+ npm install -g @simonsbs/keylore@next
95
+ keylore-http
96
+ ```
97
+
98
+ That starts KeyLore from the packaged migrations and seed data, while writable state defaults to `~/.keylore`.
99
+
100
+ To simulate a brand-new user install on the same machine without reusing your normal checkout or shell environment:
101
+
102
+ ```bash
103
+ npm run ops:fresh-user-env
104
+ ```
105
+
106
+ That launches an isolated disposable user, a fresh clone, and a separate KeyLore UI port for onboarding and MCP testing. By default it clones from the current local repo source so it also works while the repo is private.
107
+
108
+ This starts local PostgreSQL, waits for readiness, and boots KeyLore at `http://127.0.0.1:8787`.
109
+ If KeyLore is already running locally on that port, the command reuses the existing instance instead of failing.
110
+
111
+ 3. Open KeyLore in your browser:
112
+
113
+ `http://127.0.0.1:8787/`
114
+
115
+ KeyLore now redirects `/` to `/admin` and automatically opens a local operator session on loopback development installs.
116
+
117
+ If that local session bootstrap fails for any reason, use `Start working locally` or the manual sign-in form shown on the page.
118
+
119
+ 4. In `Save token`, choose the closest template for the token you are adding, such as `GitHub read-only`, `GitHub write-capable`, `npm read-only`, or `Internal service token`, then fill in:
120
+ - `Name shown in KeyLore`
121
+ - `Token key`
122
+ - `Paste token`
123
+ - `Where can it be used?`
124
+ - `Tell the AI when to use this token`
125
+
126
+ That stores the raw token outside the searchable catalogue and keeps only the LLM-facing metadata in the credential record.
127
+
128
+ 5. Review `Writing help` and `What the AI will see` in the form to confirm the agent-facing record is specific, useful, and secret-free. `Token key` is the unique identifier for the token; if KeyLore says a token already exists, change that field and save again. Open `Advanced token settings` only if you need to change storage mode, risk level, service name, tags, or write access.
129
+
130
+ 6. In `Saved tokens`, look under `Your tokens` for the ones you added yourself. `Included examples` are seeded local records and are shown separately so they do not get confused with your own tokens.
131
+
132
+ 7. In `Test credential`, choose `Token to check`, set the `URL to call with this token`, and run the check.
133
+
134
+ The check makes a real brokered `http.get` call with that token and URL. Success means the token, the target domain, and KeyLore policy all allowed the request.
135
+
136
+ 8. In `Connect your AI tool`, copy the generated Codex or Gemini CLI local snippet for the easiest setup. Use the built-in `First prompt to try` examples after you restart the client. If you want remote HTTP MCP instead, open `Remote or advanced connection options` and mint an `/mcp` token there.
137
+
138
+ Everything beyond that now sits behind `Show advanced controls` in the UI, so a first-run user can ignore tenants, OAuth client administration, approvals, backups, audit, and system internals entirely.
139
+
140
+ After creation, use `Inspect or edit AI-facing context` inside `Save token` if you need to refine the metadata without re-entering or exposing the stored secret. Saved token cards also support lightweight lifecycle actions such as rename, retag, and archive/restore under `More actions`.
141
+
142
+ When that local path stops being enough, use [docs/production-handoff.md](/home/simon/keylore/docs/production-handoff.md) to decide when to switch to external secret backends, real OAuth clients, approvals, and tenant-separated self-hosting.
143
+
144
+ ## Optional local overrides
145
+
146
+ If you want to override the local defaults, create `.env` from [.env.example](/home/simon/keylore/.env.example). KeyLore now auto-loads `.env` on startup, so you do not need to `source` it manually.
147
+
148
+ If you override `KEYLORE_BOOTSTRAP_ADMIN_CLIENT_SECRET`, the local admin quickstart button is no longer shown in the UI. At that point you are expected to sign in with your configured client credentials.
149
+
150
+ Common overrides:
151
+
152
+ ```bash
153
+ cp .env.example .env
154
+ ```
155
+
156
+ ```bash
157
+ KEYLORE_SECRET_GITHUB_READONLY=...
158
+ KEYLORE_SECRET_NPM_READONLY=...
159
+ KEYLORE_BOOTSTRAP_ADMIN_CLIENT_SECRET=...
160
+ KEYLORE_BOOTSTRAP_CONSUMER_CLIENT_SECRET=...
161
+ KEYLORE_SANDBOX_INJECTION_ENABLED=true
162
+ KEYLORE_SANDBOX_COMMAND_ALLOWLIST=/usr/bin/env,node
163
+ ```
164
+
165
+ ## Advanced local usage
166
+
167
+ Start PostgreSQL only:
168
+
169
+ ```bash
170
+ npm run db:up
171
+ ```
172
+
173
+ Start the HTTP server directly:
174
+
175
+ ```bash
176
+ npm run dev:http
177
+ ```
178
+
179
+ Or run KeyLore as a local stdio MCP server:
180
+
181
+ ```bash
182
+ npm run dev:stdio
183
+ ```
184
+
185
+ Use the local CLI:
186
+
187
+ ```bash
188
+ npm run dev:cli -- catalog list
189
+ ```
190
+
191
+ Mint an access token for the REST API:
192
+
193
+ ```bash
194
+ curl -X POST http://127.0.0.1:8787/oauth/token \
195
+ -H 'content-type: application/x-www-form-urlencoded' \
196
+ -d 'grant_type=client_credentials&client_id=keylore-admin-local&client_secret=REPLACE_ME&scope=catalog:read%20broker:use%20approval:read%20approval:review%20audit:read%20auth:read%20auth:write%20system:read%20system:write%20backup:read%20backup:write%20breakglass:request%20breakglass:read%20breakglass:review%20sandbox:run&resource=http://127.0.0.1:8787/v1'
197
+ ```
198
+
199
+ Remote tokens are tenant-scoped through their OAuth client. A tenant-bound caller only sees and mutates records from its own tenant; the local CLI continues to run as a global operator.
200
+
201
+ Interactive flows can mint a user-bound code with `POST /oauth/authorize`, then exchange it at `POST /oauth/token` with `grant_type=authorization_code` and PKCE.
202
+
203
+ Verify the health endpoint:
204
+
205
+ ```bash
206
+ curl http://127.0.0.1:8787/healthz
207
+ ```
208
+
209
+ Inspect metrics and maintenance status:
210
+
211
+ ```bash
212
+ curl http://127.0.0.1:8787/metrics
213
+ npm run dev:cli -- system maintenance
214
+ npm run dev:cli -- system traces --limit 10
215
+ npm run dev:cli -- system trace-exporter
216
+ npm run dev:cli -- system rotations list
217
+ ```
218
+
219
+ Validate the Helm deployment path:
220
+
221
+ ```bash
222
+ npm run ops:helm-validate
223
+ ```
224
+
225
+ Run the release candidate gates:
226
+
227
+ ```bash
228
+ npm run ops:release-verify
229
+ ```
230
+
231
+ Open the admin UI in a browser at `http://127.0.0.1:8787/admin`.
232
+
233
+ ## Example API usage
234
+
235
+ Search the catalogue:
236
+
237
+ ```bash
238
+ TOKEN=...
239
+ curl -X POST http://127.0.0.1:8787/v1/catalog/search \
240
+ -H "authorization: Bearer ${TOKEN}" \
241
+ -H 'content-type: application/json' \
242
+ -d '{"query":"github","limit":5}'
243
+ ```
244
+
245
+ Simulate an access request without executing it:
246
+
247
+ ```bash
248
+ TOKEN=...
249
+ curl -X POST http://127.0.0.1:8787/v1/access/simulate \
250
+ -H "authorization: Bearer ${TOKEN}" \
251
+ -H 'content-type: application/json' \
252
+ -d '{
253
+ "credentialId":"github-readonly-demo",
254
+ "operation":"http.get",
255
+ "targetUrl":"https://api.github.com/repos/modelcontextprotocol/specification"
256
+ }'
257
+ ```
258
+
259
+ Read rotation and expiry status:
260
+
261
+ ```bash
262
+ TOKEN=...
263
+ curl http://127.0.0.1:8787/v1/catalog/reports \
264
+ -H "authorization: Bearer ${TOKEN}"
265
+ ```
266
+
267
+ Request a proxy call:
268
+
269
+ ```bash
270
+ TOKEN=...
271
+ curl -X POST http://127.0.0.1:8787/v1/access/request \
272
+ -H "authorization: Bearer ${TOKEN}" \
273
+ -H 'content-type: application/json' \
274
+ -d '{
275
+ "credentialId":"github-readonly-demo",
276
+ "operation":"http.get",
277
+ "targetUrl":"https://api.github.com/repos/modelcontextprotocol/specification"
278
+ }'
279
+ ```
280
+
281
+ Run a tightly allowlisted injected command:
282
+
283
+ ```bash
284
+ TOKEN=...
285
+ curl -X POST http://127.0.0.1:8787/v1/runtime/sandbox \
286
+ -H "authorization: Bearer ${TOKEN}" \
287
+ -H 'content-type: application/json' \
288
+ -d '{
289
+ "credentialId":"github-readonly-demo",
290
+ "command":"node",
291
+ "args":["-e","console.log(process.env.GITHUB_TOKEN)"]
292
+ }'
293
+ ```
294
+
295
+ Inspect recent traces for a propagated request trace id:
296
+
297
+ ```bash
298
+ TOKEN=...
299
+ curl "http://127.0.0.1:8787/v1/system/traces?traceId=deploy-trace-123&limit=10" \
300
+ -H "authorization: Bearer ${TOKEN}"
301
+ ```
302
+
303
+ Inspect the external trace-export pipeline:
304
+
305
+ ```bash
306
+ TOKEN=...
307
+ curl http://127.0.0.1:8787/v1/system/trace-exporter \
308
+ -H "authorization: Bearer ${TOKEN}"
309
+ curl -X POST http://127.0.0.1:8787/v1/system/trace-exporter/flush \
310
+ -H "authorization: Bearer ${TOKEN}"
311
+ ```
312
+
313
+ Bootstrap a tenant and interactive client seed set:
314
+
315
+ ```bash
316
+ npm run dev:cli -- tenants bootstrap --file ./tenant-bootstrap.json
317
+ ```
318
+
319
+ Plan rotation runs:
320
+
321
+ ```bash
322
+ TOKEN=...
323
+ curl -X POST http://127.0.0.1:8787/v1/system/rotations/plan \
324
+ -H "authorization: Bearer ${TOKEN}" \
325
+ -H 'content-type: application/json' \
326
+ -d '{"horizonDays":14}'
327
+ ```
328
+
329
+ ## Example Codex configuration
330
+
331
+ See [examples/codex/config.toml](/home/simon/keylore/examples/codex/config.toml) for both `stdio` and remote HTTP MCP registration examples. For remote MCP, mint a token with `resource=http://127.0.0.1:8787/mcp` and export it into the configured client env var.
332
+
333
+ ## CLI examples
334
+
335
+ List the catalogue:
336
+
337
+ ```bash
338
+ npm run dev:cli -- catalog list
339
+ ```
340
+
341
+ Search the catalogue:
342
+
343
+ ```bash
344
+ npm run dev:cli -- catalog search --query github --limit 5
345
+ ```
346
+
347
+ Read recent audit events:
348
+
349
+ ```bash
350
+ npm run dev:cli -- audit recent --limit 10
351
+ ```
352
+
353
+ Inspect trace-export status:
354
+
355
+ ```bash
356
+ npm run dev:cli -- system trace-exporter
357
+ npm run dev:cli -- system trace-exporter flush
358
+ ```
359
+
360
+ Work rotation runs:
361
+
362
+ ```bash
363
+ npm run dev:cli -- system rotations list
364
+ npm run dev:cli -- system rotations plan --horizon-days 14
365
+ ```
366
+
367
+ Simulate a request locally:
368
+
369
+ ```bash
370
+ npm run dev:cli -- access simulate --file ./request.json
371
+ ```
372
+
373
+ Inspect rotation status locally:
374
+
375
+ ```bash
376
+ npm run dev:cli -- catalog report
377
+ ```
378
+
379
+ Create a logical backup locally:
380
+
381
+ ```bash
382
+ npm run dev:cli -- system backup create --file ./keylore-backup.json
383
+ ```
384
+
385
+ Run the restore drill locally:
386
+
387
+ ```bash
388
+ KEYLORE_DATABASE_URL=postgresql://... \
389
+ KEYLORE_BOOTSTRAP_ADMIN_CLIENT_SECRET=... \
390
+ KEYLORE_BOOTSTRAP_CONSUMER_CLIENT_SECRET=... \
391
+ npm run ops:restore-drill
392
+ ```
393
+
394
+ Validate Helm render and dry-run upgrade paths:
395
+
396
+ ```bash
397
+ npm run ops:helm-validate
398
+ ```
399
+
400
+ ## Documentation
401
+
402
+ - [docs/architecture.md](/home/simon/keylore/docs/architecture.md)
403
+ - [docs/api.md](/home/simon/keylore/docs/api.md)
404
+ - [docs/deployment.md](/home/simon/keylore/docs/deployment.md)
405
+ - [docs/configuration.md](/home/simon/keylore/docs/configuration.md)
406
+ - [docs/cli.md](/home/simon/keylore/docs/cli.md)
407
+ - [docs/observability.md](/home/simon/keylore/docs/observability.md)
408
+ - [docs/operations.md](/home/simon/keylore/docs/operations.md)
409
+ - [docs/threat-model.md](/home/simon/keylore/docs/threat-model.md)
410
+ - [docs/keylore-spec-map.md](/home/simon/keylore/docs/keylore-spec-map.md)
411
+ - [docs/roadmap.md](/home/simon/keylore/docs/roadmap.md)
412
+ - [SECURITY.md](/home/simon/keylore/SECURITY.md)
413
+
414
+ ## Development
415
+
416
+ ```bash
417
+ npm run typecheck
418
+ npm test
419
+ npm run build
420
+ ```
421
+
422
+ ## License
423
+
424
+ Licensed under Apache-2.0. See [LICENSE](/home/simon/keylore/LICENSE) and [NOTICE](/home/simon/keylore/NOTICE).
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ process.argv.push("--transport", "http");
3
+ await import("../dist/index.js");
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ process.argv.push("--transport", "stdio");
3
+ await import("../dist/index.js");