@andrewheberle/serverless-ssh-ca 0.18.2 → 0.19.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/README.md CHANGED
@@ -15,8 +15,20 @@ import app from "@andrewheberle/serverless-ssh-ca"
15
15
  export default app
16
16
  ```
17
17
 
18
- This package **only** works with Cloudflare Workers and there are no plans to make
19
- this a generic solution at this time.
18
+ This package is built for Cloudflare Workers, and Workers is the only runtime
19
+ it is tested on. There are no plans to support other runtimes at this time.
20
+
21
+ The package doesn't use any Workers-specific APIs and doesn't depend on
22
+ `@cloudflare/workers-types`. It needs:
23
+
24
+ - Web standard APIs (`Request`, `Response` and WebCrypto)
25
+ - Node.js compatibility (`nodejs_compat` on Workers), because `sshpk` uses Node APIs
26
+ - A database binding compatible with Cloudflare D1
27
+ - A secret binding with an async `get()` method that returns the CA private key
28
+
29
+ Its exported types describe only these needs, so the `Env` generated by
30
+ `wrangler types` (with `DB` as a `D1Database` and `PRIVATE_KEY` as a
31
+ `SecretsStoreSecret`) can be passed directly as `SshCaBindings`.
20
32
 
21
33
  See the following respositories for additional information:
22
34
 
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
+ import type { ExecutionContext } from "hono";
1
2
  import type { SshCaBindings } from "./types.js";
2
- export type { SshCaBindings } from "./types.js";
3
+ export type { CaDatabase, CaSecret, SshCaBindings } from "./types.js";
3
4
  declare const _default: {
4
5
  fetch(req: Request, env: SshCaBindings, ctx: ExecutionContext): Promise<Response> | Response;
5
- scheduled(controller: ScheduledController, env: SshCaBindings, ctx: ExecutionContext): Promise<void>;
6
+ scheduled(controller: unknown, env: SshCaBindings, ctx: ExecutionContext): Promise<void>;
6
7
  };
7
8
  export default _default;
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;;eAKhC,OAAO,OAAO,aAAa,OAAO,gBAAgB;0BAMjC,mBAAmB,OAAO,aAAa,OAAO,gBAAgB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,MAAM,CAAA;AAG5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;;eAWtD,OAAO,OAAO,aAAa,OAAO,gBAAgB;0BAMjC,OAAO,OAAO,aAAa,OAAO,gBAAgB"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAIvC,IAAI,GAA6C,CAAA;AAEjD,eAAe;IACX,KAAK,CAAC,GAAY,EAAE,GAAkB,EAAE,GAAqB;QACzD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACpB,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;QACxB,CAAC;QACD,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACnC,CAAC;IACD,KAAK,CAAC,SAAS,CAAC,UAA+B,EAAE,GAAkB,EAAE,GAAqB;QACtF,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IACjC,CAAC;CACqC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAUvC,IAAI,GAA6C,CAAA;AAEjD,eAAe;IACX,KAAK,CAAC,GAAY,EAAE,GAAkB,EAAE,GAAqB;QACzD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACpB,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;QACxB,CAAC;QACD,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACnC,CAAC;IACD,KAAK,CAAC,SAAS,CAAC,UAAmB,EAAE,GAAkB,EAAE,GAAqB;QAC1E,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IACjC,CAAC;CACmB,CAAA"}
package/dist/router.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { type Context } from "hono";
2
2
  import type { SshCaBindings } from "./types.js";
3
- export type CFArgs = [SshCaBindings, ExecutionContext];
4
3
  export type AppContext = Context<{
5
4
  Bindings: SshCaBindings;
6
5
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,MAAM,CAAA;AAIzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,MAAM,MAAM,MAAM,GAAG,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAA;AACtD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC,CAAA;AAE7D,eAAO,MAAM,SAAS,QAAS,aAAa,mHA+B3C,CAAA"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,MAAM,CAAA;AAIzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC,CAAA;AAE7D,eAAO,MAAM,SAAS,QAAS,aAAa,mHA+B3C,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAA;AACzC,OAAO,EAAE,SAAS,IAAI,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAMpC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAkB,EAAE,EAAE;IAC5C,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAA;IAEvB,qBAAqB;IACrB,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACpB,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YAC/B,OAAO,GAAG,CAAC,WAAW,EAAE,CAAA;QAC5B,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,8BAA8B,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;QAC/D,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IACtG,CAAC,CAAC,CAAA;IAEF,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE;QAC7B,MAAM,EAAE;YACP,IAAI,EAAE;gBACL,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,OAAO;aAChB;SACD;KACD,CAAC,CAAA;IAEC,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,iBAAiB,EAAE,UAAU,EAAE;QAC1D,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,KAAK;KACtB,CAAC,CAAA;IAEF,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;IAEhC,OAAO,GAAG,CAAA;AACd,CAAC,CAAA"}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAA;AACzC,OAAO,EAAE,SAAS,IAAI,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAKpC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAkB,EAAE,EAAE;IAC5C,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAA;IAEvB,qBAAqB;IACrB,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACpB,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YAC/B,OAAO,GAAG,CAAC,WAAW,EAAE,CAAA;QAC5B,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,8BAA8B,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;QAC/D,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IACtG,CAAC,CAAC,CAAA;IAEF,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE;QAC7B,MAAM,EAAE;YACP,IAAI,EAAE;gBACL,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,OAAO;aAChB;SACD;KACD,CAAC,CAAA;IAEC,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,iBAAiB,EAAE,UAAU,EAAE;QAC1D,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,KAAK;KACtB,CAAC,CAAA;IAEF,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;IAEhC,OAAO,GAAG,CAAA;AACd,CAAC,CAAA"}
package/dist/types.d.ts CHANGED
@@ -19,10 +19,33 @@ export type SSHExtension = {
19
19
  name: string;
20
20
  data: Buffer<ArrayBuffer>;
21
21
  };
22
+ /**
23
+ * The subset of a Cloudflare D1 database binding used by the CA.
24
+ *
25
+ * A Workers `D1Database` binding satisfies this structurally, so the package
26
+ * does not need to depend on `@cloudflare/workers-types`.
27
+ */
28
+ export interface CaDatabase {
29
+ prepare(query: string): unknown;
30
+ batch(statements: never[]): Promise<unknown>;
31
+ exec(query: string): Promise<unknown>;
32
+ }
33
+ /**
34
+ * The subset of a Cloudflare Secrets Store binding used to load the CA private key.
35
+ *
36
+ * A Workers `SecretsStoreSecret` binding satisfies this structurally.
37
+ */
38
+ export interface CaSecret {
39
+ get(): Promise<string>;
40
+ }
41
+ /**
42
+ * The bindings (environment) the CA expects, see {@link CaDatabase} and
43
+ * {@link CaSecret} for the non-string bindings.
44
+ */
22
45
  export interface SshCaBindings {
23
- DB: D1Database;
46
+ DB: CaDatabase;
24
47
  DB_CERTIFICATE_RETENTION: string;
25
- PRIVATE_KEY: SecretsStoreSecret;
48
+ PRIVATE_KEY: CaSecret;
26
49
  SSH_CERTIFICATE_EXTENSIONS: string;
27
50
  SSH_CERTIFICATE_LIFETIME: string;
28
51
  SSH_CERTIFICATE_INCLUDE_SELF?: string | boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AAGjC,MAAM,MAAM,wBAAwB,GAAG;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAA;CACtB,CAAA;AAGD,MAAM,MAAM,4BAA4B,GAAG;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;CACnC,GAAG,UAAU,CAAA;AAEd,MAAM,MAAM,YAAY,GAAG;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;CAC5B,CAAA;AAED,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,UAAU,CAAA;IACd,wBAAwB,EAAE,MAAM,CAAA;IAChC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,0BAA0B,EAAE,MAAM,CAAA;IAClC,wBAAwB,EAAE,MAAM,CAAA;IAChC,4BAA4B,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAC/C,kCAAkC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACrD,0BAA0B,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC9C,6BAA6B,EAAE,MAAM,CAAA;IACrC,mCAAmC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACvD,kCAAkC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACtD,SAAS,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACjC,oCAAoC,EAAE,MAAM,CAAA;IAC5C,iCAAiC,EAAE,MAAM,CAAA;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AAGjC,MAAM,MAAM,wBAAwB,GAAG;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAA;CACtB,CAAA;AAGD,MAAM,MAAM,4BAA4B,GAAG;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;CACnC,GAAG,UAAU,CAAA;AAEd,MAAM,MAAM,YAAY,GAAG;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;CAC5B,CAAA;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACvB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;IAC/B,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5C,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxC;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACrB,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,UAAU,CAAA;IACd,wBAAwB,EAAE,MAAM,CAAA;IAChC,WAAW,EAAE,QAAQ,CAAA;IACrB,0BAA0B,EAAE,MAAM,CAAA;IAClC,wBAAwB,EAAE,MAAM,CAAA;IAChC,4BAA4B,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAC/C,kCAAkC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACrD,0BAA0B,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC9C,6BAA6B,EAAE,MAAM,CAAA;IACrC,mCAAmC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACvD,kCAAkC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACtD,SAAS,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACjC,oCAAoC,EAAE,MAAM,CAAA;IAC5C,iCAAiC,EAAE,MAAM,CAAA;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andrewheberle/serverless-ssh-ca",
3
- "version": "0.18.2",
3
+ "version": "0.19.0",
4
4
  "description": "A serverless SSH CA built on Cloudflare Workers",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -31,17 +31,17 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@andrewheberle/ts-slog": "^1.3.0",
34
- "@cloudflare/workers-types": "^5.0.0",
35
34
  "chanfana": "^3.0.0",
36
35
  "hono": "^4.10.6",
37
36
  "itty-time": "^2.0.2",
38
37
  "jose": "^6.0.12",
39
- "workers-qb": "^1.14.0",
40
38
  "sshpk": "^1.18.0",
39
+ "workers-qb": "^1.14.0",
41
40
  "zod": "^4.0.0"
42
41
  },
43
42
  "devDependencies": {
44
43
  "@eslint/js": "^10.0.1",
44
+ "@types/node": "^24.19.1",
45
45
  "@types/sshpk": "^1.17.4",
46
46
  "@vitest/coverage-v8": "^4.1.7",
47
47
  "eslint": "^10.4.1",
package/src/index.ts CHANGED
@@ -1,7 +1,14 @@
1
+ import type { ExecutionContext } from "hono"
1
2
  import { dbCleanup } from "./db/index.js"
2
3
  import { createApp } from "./router.js"
3
4
  import type { SshCaBindings } from "./types.js"
4
- export type { SshCaBindings } from "./types.js"
5
+ export type { CaDatabase, CaSecret, SshCaBindings } from "./types.js"
6
+
7
+ // the handlers the CA exposes, compatible with a Cloudflare Workers ExportedHandler
8
+ type SshCaHandler = {
9
+ fetch(req: Request, env: SshCaBindings, ctx: ExecutionContext): Response | Promise<Response>
10
+ scheduled(controller: unknown, env: SshCaBindings, ctx: ExecutionContext): Promise<void>
11
+ }
5
12
 
6
13
  let app: ReturnType<typeof createApp> | undefined
7
14
 
@@ -12,7 +19,7 @@ export default {
12
19
  }
13
20
  return app.fetch(req, env, ctx)
14
21
  },
15
- async scheduled(controller: ScheduledController, env: SshCaBindings, ctx: ExecutionContext) {
22
+ async scheduled(controller: unknown, env: SshCaBindings, ctx: ExecutionContext) {
16
23
  ctx.waitUntil(dbCleanup(env))
17
24
  },
18
- } satisfies ExportedHandler<SshCaBindings>
25
+ } satisfies SshCaHandler
package/src/krl.ts CHANGED
@@ -123,7 +123,7 @@ function base64url(bytes: Uint8Array): string {
123
123
  async function importPrivateKey(caKey: PrivateKey): Promise<{
124
124
  cryptoKey: CryptoKey
125
125
  sigAlgo: string // SSH signature algorithm name
126
- webCryptoAlgo: SubtleCryptoSignAlgorithm
126
+ webCryptoAlgo: Parameters<SubtleCrypto["sign"]>[0]
127
127
  }> {
128
128
  const type = caKey.type // "ed25519" | "ecdsa" | etc.
129
129
  const curve = (caKey as unknown as { curve?: string }).curve
package/src/router.ts CHANGED
@@ -5,7 +5,6 @@ import { HTTPException } from "hono/http-exception"
5
5
  import { logger } from "./logger.js"
6
6
  import type { SshCaBindings } from "./types.js"
7
7
 
8
- export type CFArgs = [SshCaBindings, ExecutionContext]
9
8
  export type AppContext = Context<{ Bindings: SshCaBindings }>
10
9
 
11
10
  export const createApp = (env: SshCaBindings) => {
package/src/types.ts CHANGED
@@ -26,10 +26,35 @@ export type SSHExtension = {
26
26
  data: Buffer<ArrayBuffer>
27
27
  }
28
28
 
29
+ /**
30
+ * The subset of a Cloudflare D1 database binding used by the CA.
31
+ *
32
+ * A Workers `D1Database` binding satisfies this structurally, so the package
33
+ * does not need to depend on `@cloudflare/workers-types`.
34
+ */
35
+ export interface CaDatabase {
36
+ prepare(query: string): unknown
37
+ batch(statements: never[]): Promise<unknown>
38
+ exec(query: string): Promise<unknown>
39
+ }
40
+
41
+ /**
42
+ * The subset of a Cloudflare Secrets Store binding used to load the CA private key.
43
+ *
44
+ * A Workers `SecretsStoreSecret` binding satisfies this structurally.
45
+ */
46
+ export interface CaSecret {
47
+ get(): Promise<string>
48
+ }
49
+
50
+ /**
51
+ * The bindings (environment) the CA expects, see {@link CaDatabase} and
52
+ * {@link CaSecret} for the non-string bindings.
53
+ */
29
54
  export interface SshCaBindings {
30
- DB: D1Database
55
+ DB: CaDatabase
31
56
  DB_CERTIFICATE_RETENTION: string
32
- PRIVATE_KEY: SecretsStoreSecret
57
+ PRIVATE_KEY: CaSecret
33
58
  SSH_CERTIFICATE_EXTENSIONS: string
34
59
  SSH_CERTIFICATE_LIFETIME: string
35
60
  SSH_CERTIFICATE_INCLUDE_SELF?: string | boolean