@artifact-keeper/sdk 1.6.0 → 1.7.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/src/types.gen.ts CHANGED
@@ -303,7 +303,19 @@ export type ArtifactListResponse = {
303
303
  * Docker tag grouping. Only present when `group_by=docker_tag`.
304
304
  */
305
305
  docker_tags?: Array<DockerTagResponse> | null;
306
+ /**
307
+ * Whether another page exists after this one (#2520, #2518). Present on
308
+ * keyset-paged listings (flat and grouped); authoritative regardless of
309
+ * the `pagination.total` mode (exact vs lower bound).
310
+ */
311
+ has_more?: boolean | null;
306
312
  items: Array<ArtifactResponse>;
313
+ /**
314
+ * Opaque keyset cursor for the next page (#2520, #2518). Present on
315
+ * keyset-paged listings (flat and grouped) when another page exists;
316
+ * pass it back via `?cursor=`.
317
+ */
318
+ next_cursor?: string | null;
307
319
  pagination: Pagination;
308
320
  };
309
321
 
@@ -353,6 +365,31 @@ export type ArtifactResponse = {
353
365
  } | null;
354
366
  name: string;
355
367
  path: string;
368
+ /**
369
+ * Per-artifact quarantine state so a client/operator can tell which
370
+ * listed artifacts are held for security review (#2940). Always
371
+ * serialized so the listing never hides the control:
372
+ * - `"quarantined"` — held pending review; downloads return 409 (until
373
+ * any `quarantine_until` lapses),
374
+ * - `"rejected"` — terminally blocked by an admin,
375
+ * - a scan-lifecycle state (`"clean"`, `"flagged"`, `"unscanned"`,
376
+ * `"released"`),
377
+ * - `"not_quarantined"` — the explicit default when the row carries no
378
+ * quarantine state, so clients never have to treat a missing value as
379
+ * a state.
380
+ *
381
+ * The human-readable *reason* is intentionally NOT surfaced here: it is
382
+ * per-artifact security detail disclosed only by the authenticated,
383
+ * repository-visibility-checked `GET /api/v1/quarantine/{id}` (#2912),
384
+ * whereas this listing is reachable anonymously on public repositories.
385
+ */
386
+ quarantine_status: string;
387
+ /**
388
+ * When a timed quarantine hold lapses and the artifact becomes
389
+ * downloadable again. `None` for a permanent (admin) quarantine and for
390
+ * artifacts that are not quarantined. (#2940)
391
+ */
392
+ quarantine_until?: string | null;
356
393
  repository_key: string;
357
394
  /**
358
395
  * Server-assigned revision number for repositories with first-class
@@ -496,6 +533,18 @@ export type AuthConfig = {
496
533
  * Whether an LDAP directory is configured.
497
534
  */
498
535
  ldap_enabled: boolean;
536
+ /**
537
+ * Whether the login UI should offer the local username/password form
538
+ * (issue #2621). `true` when no SSO provider is enabled; with SSO
539
+ * enabled it is `true` only when the operator explicitly opted in via
540
+ * `ALLOW_LOCAL_ADMIN_LOGIN=true` and has not enforced strict SSO-only
541
+ * via `SSO_DISABLE_ADMIN_BREAK_GLASS`. Display-only: the login endpoint
542
+ * independently enforces the same policy server-side
543
+ * (`api::handlers::auth::local_login_gate`), so this flag never grants
544
+ * access by itself. LDAP is separate — the UI shows the credentials form
545
+ * for enabled LDAP providers regardless of this flag.
546
+ */
547
+ local_login_enabled: boolean;
499
548
  /**
500
549
  * Whether an OIDC provider is configured.
501
550
  */
@@ -1023,7 +1072,40 @@ export type CreateApiTokenResponse = {
1023
1072
  };
1024
1073
 
1025
1074
  export type CreateBackupRequest = {
1075
+ /**
1076
+ * Repository ids to exclude from a full or incremental backup (#2772).
1077
+ *
1078
+ * Airgapped or bandwidth-limited deployments use this to keep specific
1079
+ * repositories out of the backup. When omitted or empty nothing is
1080
+ * excluded, so existing behavior is unchanged. If `repository_ids` is
1081
+ * also supplied the excluded ids are removed from that include list;
1082
+ * otherwise every repository except the excluded ones is backed up.
1083
+ */
1084
+ exclude_repositories?: Array<string> | null;
1085
+ /**
1086
+ * Optional custom name/label for the backup archive (#2790).
1087
+ *
1088
+ * When provided it becomes the identifying part of the archive
1089
+ * filename. Restricted to letters, digits, `.`, `_`, and `-`; when
1090
+ * omitted the archive keeps its default `{uuid}` name.
1091
+ */
1092
+ name?: string | null;
1093
+ /**
1094
+ * Explicit allow-list of repository ids to include in the backup.
1095
+ *
1096
+ * When omitted every repository is backed up (subject to
1097
+ * `exclude_repositories`).
1098
+ */
1026
1099
  repository_ids?: Array<string> | null;
1100
+ /**
1101
+ * Optional RFC3339 lower bound on artifact modification time (#2789).
1102
+ *
1103
+ * When set, the (typically incremental) backup includes only artifacts
1104
+ * whose `updated_at` is at or after this timestamp, capturing just the
1105
+ * changes made from the given date/time to now. When omitted every
1106
+ * artifact is included, so backup behavior is unchanged.
1107
+ */
1108
+ since?: string | null;
1027
1109
  type?: string | null;
1028
1110
  };
1029
1111
 
@@ -1122,11 +1204,24 @@ export type CreateLdapConfigRequest = {
1122
1204
  admin_group_dn?: string | null;
1123
1205
  bind_dn?: string | null;
1124
1206
  bind_password?: string | null;
1207
+ /**
1208
+ * Inline PEM CA certificate/chain to trust for this provider's LDAPS/
1209
+ * STARTTLS handshake (migration 174, #2782). Send an empty string to
1210
+ * clear a previously stored certificate.
1211
+ */
1212
+ ca_certificate?: string | null;
1125
1213
  display_name_attribute?: string | null;
1126
1214
  email_attribute?: string | null;
1127
1215
  group_base_dn?: string | null;
1128
1216
  group_filter?: string | null;
1129
1217
  groups_attribute?: string | null;
1218
+ /**
1219
+ * Opt-in (migration 174, #2782): skip TLS certificate verification for
1220
+ * this provider's LDAPS/STARTTLS handshake. Defaults false
1221
+ * (secure-by-default). Only enable for trusted networks / private CAs
1222
+ * you cannot import.
1223
+ */
1224
+ insecure_skip_verify?: boolean | null;
1130
1225
  is_enabled?: boolean | null;
1131
1226
  name: string;
1132
1227
  priority?: number | null;
@@ -1285,6 +1380,14 @@ export type CreateRepositoryRequest = {
1285
1380
  * Stored in `repository_config` under `apt_release_version`.
1286
1381
  */
1287
1382
  apt_release_version?: string | null;
1383
+ /**
1384
+ * Opt into ingesting UNVERIFIED upstream metadata on the keyless RPM
1385
+ * curation-sync path (#2569). Omit or `false` to keep the fail-closed
1386
+ * default (a keyless curation sync refuses to ingest unverified upstream
1387
+ * packages); `true` reverts to the legacy unverified-ingest behavior. Only
1388
+ * meaningful for RPM curation staging repositories.
1389
+ */
1390
+ curation_allow_unverified?: boolean | null;
1288
1391
  /**
1289
1392
  * Custom User-Agent sent on outbound HTTP requests to the upstream for
1290
1393
  * this repository. Only valid for remote repositories. Max 256 characters.
@@ -1626,6 +1729,7 @@ export type CreateWebhookRequest = {
1626
1729
  export type CreatedGroupRow = {
1627
1730
  created_at: string;
1628
1731
  description?: string | null;
1732
+ external_source?: string | null;
1629
1733
  id: string;
1630
1734
  name: string;
1631
1735
  updated_at: string;
@@ -1645,9 +1749,33 @@ export type CreatedPermissionRow = {
1645
1749
  export type CurationCreateRuleRequest = {
1646
1750
  action: string;
1647
1751
  architecture?: string;
1648
- package_pattern: string;
1752
+ /**
1753
+ * Engine-specific parameters (JSON object). `{}` for `pattern` rules.
1754
+ */
1755
+ config?: {
1756
+ [key: string]: unknown;
1757
+ };
1758
+ /**
1759
+ * Only meaningful for `rule_type = "pattern"`; defaults to `*` so typed
1760
+ * rules (`publisher_trust`, `popularity`) can omit it.
1761
+ */
1762
+ package_pattern?: string;
1649
1763
  priority?: number;
1650
1764
  reason: string;
1765
+ /**
1766
+ * Evaluation engine: `pattern` (default), `publisher_trust`, `popularity`.
1767
+ */
1768
+ rule_type?: string;
1769
+ /**
1770
+ * `repository` (default when `staging_repo_id` is set) or `global`.
1771
+ * When present it must be consistent with `staging_repo_id`: `global`
1772
+ * forbids a repo id, `repository` requires one.
1773
+ */
1774
+ scope?: string | null;
1775
+ /**
1776
+ * Omit (with `scope: "global"` or no `scope`) to create an instance-wide
1777
+ * baseline rule; set to attach the rule to one staging repository.
1778
+ */
1651
1779
  staging_repo_id?: string | null;
1652
1780
  version_constraint?: string;
1653
1781
  };
@@ -1677,10 +1805,20 @@ export type CurationPackageResponse = {
1677
1805
  export type CurationUpdateRuleRequest = {
1678
1806
  action: string;
1679
1807
  architecture?: string;
1808
+ /**
1809
+ * Engine-specific parameters (JSON object). `{}` for `pattern` rules.
1810
+ */
1811
+ config?: {
1812
+ [key: string]: unknown;
1813
+ };
1680
1814
  enabled?: boolean;
1681
1815
  package_pattern: string;
1682
1816
  priority?: number;
1683
1817
  reason: string;
1818
+ /**
1819
+ * Evaluation engine: `pattern` (default), `publisher_trust`, `popularity`.
1820
+ */
1821
+ rule_type?: string;
1684
1822
  version_constraint?: string;
1685
1823
  };
1686
1824
 
@@ -1807,6 +1945,7 @@ export type DbPoolStats = {
1807
1945
  * the default when none exists yet.
1808
1946
  */
1809
1947
  export type DebianConfigPatch = {
1948
+ allow_encoded_separators?: boolean | null;
1810
1949
  architectures?: Array<string> | null;
1811
1950
  components?: Array<string> | null;
1812
1951
  distribution_paths?: Array<string> | null;
@@ -1846,6 +1985,15 @@ export type DebianPackageFetchStrategy = 'upstream_passthrough' | 'eager';
1846
1985
  * permitted regardless of the `architectures` allowlist.
1847
1986
  */
1848
1987
  export type DebianRepositoryConfig = {
1988
+ /**
1989
+ * Defense-in-depth (#2562): when `false` (the default) a proxy request
1990
+ * whose path carries a percent-encoded path separator (`%2f` = `/`,
1991
+ * `%5c` = `\`, at any decode layer) is rejected with 400 before any
1992
+ * upstream fetch. APT never percent-encodes path separators, so this only
1993
+ * ever blocks path-confusion/traversal probes; set it `true` to opt out
1994
+ * for a nonstandard upstream that genuinely requires encoded separators.
1995
+ */
1996
+ allow_encoded_separators?: boolean;
1849
1997
  /**
1850
1998
  * Architectures (e.g. `amd64`, `arm64`) to proxy. Empty/`["*"]` = all.
1851
1999
  * `all` (arch-independent) is always permitted.
@@ -2029,6 +2177,13 @@ export type DownloadRecord = {
2029
2177
  export type DownloadTrend = {
2030
2178
  date: string;
2031
2179
  download_count: number;
2180
+ /**
2181
+ * Proxy-served (pull-through) downloads for the day, from the sibling
2182
+ * `proxy_download_statistics` table (#2537/#2704). Additive: hosted
2183
+ * serves stay in `download_count` unchanged; defaults to 0 when
2184
+ * deserializing older payloads.
2185
+ */
2186
+ proxy_download_count?: number;
2032
2187
  };
2033
2188
 
2034
2189
  /**
@@ -2476,6 +2631,10 @@ export type GroupMemberResponse = {
2476
2631
  export type GroupResponse = {
2477
2632
  created_at: string;
2478
2633
  description?: string | null;
2634
+ /**
2635
+ * See [`GroupRow::external_source`]; lets the frontend disable member editing for SSO groups.
2636
+ */
2637
+ external_source?: string | null;
2479
2638
  id: string;
2480
2639
  member_count: number;
2481
2640
  name: string;
@@ -2485,6 +2644,10 @@ export type GroupResponse = {
2485
2644
  export type GroupRow = {
2486
2645
  created_at: string;
2487
2646
  description?: string | null;
2647
+ /**
2648
+ * SSO provider owning the group (`oidc`/`saml`/`ldap`); `None` for local groups. IdP owns membership (#2874).
2649
+ */
2650
+ external_source?: string | null;
2488
2651
  id: string;
2489
2652
  member_count: number;
2490
2653
  name: string;
@@ -2643,7 +2806,20 @@ export type LdapConfigResponse = {
2643
2806
  group_filter?: string | null;
2644
2807
  groups_attribute: string;
2645
2808
  has_bind_password: boolean;
2809
+ /**
2810
+ * Whether a custom inline CA certificate is configured for this provider
2811
+ * (migration 174, #2782). The PEM itself is not returned.
2812
+ */
2813
+ has_ca_certificate: boolean;
2646
2814
  id: string;
2815
+ /**
2816
+ * Opt-in flag (migration 174, #2782): when true, TLS certificate
2817
+ * verification is skipped for this provider's LDAPS/STARTTLS handshake.
2818
+ * Defaults false (secure-by-default). Matches Harbor's "insecure skip
2819
+ * verify"; only enable for trusted networks / private CAs you cannot
2820
+ * import.
2821
+ */
2822
+ insecure_skip_verify: boolean;
2647
2823
  is_enabled: boolean;
2648
2824
  name: string;
2649
2825
  priority: number;
@@ -2711,6 +2887,23 @@ export type LifecyclePolicy = {
2711
2887
  };
2712
2888
 
2713
2889
  export type ListArtifactsQuery = {
2890
+ /**
2891
+ * Total-count mode for keyset-paged listings (#2520, #2519).
2892
+ * `count=exact` runs a dedicated COUNT query so `pagination.total` is
2893
+ * exact; otherwise the keyset-paged listings report a cheap lower bound
2894
+ * (rows seen so far, +1 when another page exists) and `has_more` is the
2895
+ * authoritative "is there a next page" signal.
2896
+ */
2897
+ count?: string | null;
2898
+ /**
2899
+ * Opaque keyset cursor (#2520, #2519, #2518). Pass the `next_cursor`
2900
+ * value from the previous response to fetch the next page; `page` is
2901
+ * ignored while a cursor is present. Supported by the flat artifact
2902
+ * listing of hosted/local, virtual, and remote repositories (#2518,
2903
+ * #2519), by `group_by=docker_tag`, and by `group_by=maven_component`
2904
+ * on remote repositories; other listing modes ignore it.
2905
+ */
2906
+ cursor?: string | null;
2714
2907
  /**
2715
2908
  * Server-side artifact grouping.
2716
2909
  *
@@ -3715,9 +3908,23 @@ export type QuarantineActionResponse = {
3715
3908
  new_status: string;
3716
3909
  };
3717
3910
 
3911
+ export type QuarantineNowRequest = {
3912
+ /**
3913
+ * Reason shown to developers whose downloads are blocked.
3914
+ */
3915
+ reason?: string | null;
3916
+ };
3917
+
3718
3918
  export type QuarantineStatusResponse = {
3719
3919
  artifact_id: string;
3720
3920
  is_blocked: boolean;
3921
+ /**
3922
+ * Why the artifact is held, when one was recorded by a scan policy or an
3923
+ * admin. This is the only surface that discloses the reason: blocked
3924
+ * downloads return a generic message because they are reachable
3925
+ * anonymously on public repositories (#2912).
3926
+ */
3927
+ quarantine_reason?: string | null;
3721
3928
  quarantine_status?: string | null;
3722
3929
  quarantine_until?: string | null;
3723
3930
  };
@@ -3920,6 +4127,19 @@ export type RepositoryResponse = {
3920
4127
  */
3921
4128
  apt_release_version?: string | null;
3922
4129
  created_at: string;
4130
+ /**
4131
+ * Stance applied when no curation rule matches: `allow` or `review`.
4132
+ */
4133
+ curation_default_action: string;
4134
+ /**
4135
+ * Whether curation rules are enforced for this repository (#2912).
4136
+ *
4137
+ * Echoed back because this flag now *blocks downloads* on the PyPI proxy
4138
+ * paths, and a security control that cannot be read back is the same class of
4139
+ * problem as one that is stored but not enforced. Stored on the repositories
4140
+ * row, so unlike `quarantine_enabled` this needs no separate lookup.
4141
+ */
4142
+ curation_enabled: boolean;
3923
4143
  /**
3924
4144
  * Custom User-Agent used for outbound HTTP requests to the upstream,
3925
4145
  * read back from `repository_config`. `None` when unset.
@@ -4024,6 +4244,15 @@ export type RepositoryStorageBreakdown = {
4024
4244
  download_count: number;
4025
4245
  format: string;
4026
4246
  last_upload_at?: string | null;
4247
+ /**
4248
+ * Downloads served by this repository's remote pull-through proxy
4249
+ * (`proxy_download_statistics`, #2537/#2704). Proxy-cached objects carry
4250
+ * no `artifacts` row (#1280), so these serves are counted in a sibling
4251
+ * table and were previously not readable through any API. Kept separate
4252
+ * from `download_count` (hosted serves) so existing consumers are
4253
+ * unaffected; defaults to 0 when deserializing older payloads.
4254
+ */
4255
+ proxy_download_count?: number;
4027
4256
  repository_id: string;
4028
4257
  repository_key: string;
4029
4258
  repository_name: string;
@@ -4107,6 +4336,52 @@ export type RepositoryStorageStatsResponse = {
4107
4336
  unique_bytes?: number | null;
4108
4337
  };
4109
4338
 
4339
+ /**
4340
+ * Per-prefix (folder tree) storage rollup response (#2601).
4341
+ *
4342
+ * All figures are read from the materialized `repository_path_storage_stats`
4343
+ * cache (refreshed on the storage-stats schedule + post-GC) — a tree call is
4344
+ * an index scan over pre-aggregated rows, never a walk of the artifact table.
4345
+ *
4346
+ * Every figure is within-repository only (references this repo holds), so
4347
+ * unlike the repo-level endpoint's cross-tenant-derivable dedup breakdown
4348
+ * (#2560) nothing here needs an admin restriction beyond repo visibility.
4349
+ */
4350
+ export type RepositoryStorageTreeResponse = {
4351
+ /**
4352
+ * Descendant folder nodes, up to `depth` levels below `node`, largest
4353
+ * `logical_bytes` first.
4354
+ */
4355
+ children: Array<StorageTreeNode>;
4356
+ /**
4357
+ * When the rollup was last recomputed. `null` before the first refresh.
4358
+ */
4359
+ computed_at?: string | null;
4360
+ /**
4361
+ * Folder levels below the root that are individually materialized;
4362
+ * deeper files roll up into their ancestor at this depth.
4363
+ */
4364
+ max_materialized_depth: number;
4365
+ /**
4366
+ * The node the listing is rooted at (zeros when the prefix has no
4367
+ * materialized data — unknown folder or refresher not yet run).
4368
+ */
4369
+ node: StorageTreeNode;
4370
+ repository_key: string;
4371
+ /**
4372
+ * True when `limit` cut the descendant listing.
4373
+ */
4374
+ truncated: boolean;
4375
+ /**
4376
+ * Bytes referenced by this repository that carry no logical path and so
4377
+ * cannot be placed in the tree (today: OCI layer blobs; the blob→image
4378
+ * edge lives only in manifest content). Root-level figure; present only
4379
+ * when the request is rooted at `''`. `node.logical_bytes +
4380
+ * unattributed_bytes` reconciles with the repo-level logical total.
4381
+ */
4382
+ unattributed_bytes?: number | null;
4383
+ };
4384
+
4110
4385
  export type RescanForInventoryRequest = {
4111
4386
  /**
4112
4387
  * Maximum number of artifacts to enqueue in this call. Operators
@@ -4187,6 +4462,12 @@ export type RoleResponse = {
4187
4462
 
4188
4463
  /**
4189
4464
  * Response returned by the rotate-secret endpoint.
4465
+ *
4466
+ * GHSA-qcmj: the raw signing secret is intentionally NOT returned here. A
4467
+ * rotation only reports success and non-reversible metadata (the display
4468
+ * `secret_digest` and the previous-secret expiry); the new raw secret is
4469
+ * retained only in encrypted form and delivered/consumed out-of-band, so it
4470
+ * cannot be disclosed via this response body or logs.
4190
4471
  */
4191
4472
  export type RotateWebhookSecretResponse = {
4192
4473
  id: string;
@@ -4195,9 +4476,8 @@ export type RotateWebhookSecretResponse = {
4195
4476
  */
4196
4477
  previous_secret_expires_at: string;
4197
4478
  /**
4198
- * Raw signing secret produced by this rotation. Shown exactly once.
4479
+ * Short, non-reversible identifier for the newly active signing secret.
4199
4480
  */
4200
- secret: string;
4201
4481
  secret_digest: string;
4202
4482
  };
4203
4483
 
@@ -4232,6 +4512,9 @@ export type RuleEvaluationResponse = {
4232
4512
  export type RuleResponse = {
4233
4513
  action: string;
4234
4514
  architecture: string;
4515
+ config: {
4516
+ [key: string]: unknown;
4517
+ };
4235
4518
  created_at: string;
4236
4519
  created_by?: string | null;
4237
4520
  enabled: boolean;
@@ -4239,6 +4522,8 @@ export type RuleResponse = {
4239
4522
  package_pattern: string;
4240
4523
  priority: number;
4241
4524
  reason: string;
4525
+ rule_type: string;
4526
+ scope: string;
4242
4527
  staging_repo_id?: string | null;
4243
4528
  updated_at: string;
4244
4529
  version_constraint: string;
@@ -4317,6 +4602,11 @@ export type ScanConfigResponse = {
4317
4602
  block_on_policy_violation: boolean;
4318
4603
  created_at: string;
4319
4604
  id: string;
4605
+ /**
4606
+ * #2954: fail-open (default) / fail-closed action for the inline proxy
4607
+ * scan-on-fetch.
4608
+ */
4609
+ proxy_scan_action: string;
4320
4610
  repository_id: string;
4321
4611
  scan_enabled: boolean;
4322
4612
  scan_on_proxy: boolean;
@@ -4553,6 +4843,13 @@ export type SetRoutingRulesRequest = {
4553
4843
  * Response body for the setup status endpoint.
4554
4844
  */
4555
4845
  export type SetupStatusResponse = {
4846
+ /**
4847
+ * Optional deployment-aware instruction for retrieving the generated
4848
+ * initial admin password, sourced from the `SETUP_PASSWORD_HINT` env var.
4849
+ * Present only when an operator has configured it; when absent, the web UI
4850
+ * falls back to its built-in Docker Compose instruction (#2802).
4851
+ */
4852
+ setup_password_hint?: string | null;
4556
4853
  /**
4557
4854
  * Whether the initial admin password change is still required.
4558
4855
  */
@@ -4725,6 +5022,61 @@ export type StorageSnapshot = {
4725
5022
  total_users: number;
4726
5023
  };
4727
5024
 
5025
+ /**
5026
+ * One folder node in the per-prefix storage rollup (#2601).
5027
+ */
5028
+ export type StorageTreeNode = {
5029
+ /**
5030
+ * Distinct physical objects under this prefix.
5031
+ */
5032
+ blob_count: number;
5033
+ /**
5034
+ * Number of path segments in `prefix` (0 = root).
5035
+ */
5036
+ depth: number;
5037
+ /**
5038
+ * References (artifact/proxy-cache rows) under this prefix.
5039
+ */
5040
+ file_count: number;
5041
+ /**
5042
+ * Sum over every artifact/proxy-cache reference under this prefix.
5043
+ */
5044
+ logical_bytes: number;
5045
+ /**
5046
+ * Deduplicated within this repository: each distinct physical object
5047
+ * under the prefix counted once. Because an object shared by two sibling
5048
+ * subtrees counts once in each but once at their common ancestor, the sum
5049
+ * of children's `physical_bytes` can exceed the parent's — the difference
5050
+ * is the cross-subtree dedup saving.
5051
+ */
5052
+ physical_bytes: number;
5053
+ /**
5054
+ * Canonical prefix (no leading/trailing `/`; `''` = repository root).
5055
+ */
5056
+ prefix: string;
5057
+ };
5058
+
5059
+ /**
5060
+ * Query parameters for the per-prefix storage tree (#2601).
5061
+ */
5062
+ export type StorageTreeQuery = {
5063
+ /**
5064
+ * How many tree levels below `prefix` to return (default 1 = immediate
5065
+ * children, clamped to 1..=5).
5066
+ */
5067
+ depth?: number | null;
5068
+ /**
5069
+ * Maximum number of descendant nodes returned (default 200, clamped to
5070
+ * 1..=1000). `truncated` is set when the limit cut the listing.
5071
+ */
5072
+ limit?: number | null;
5073
+ /**
5074
+ * Folder prefix to root the listing at (`''`/absent = repository root).
5075
+ * Leading/trailing slashes are ignored.
5076
+ */
5077
+ prefix?: string | null;
5078
+ };
5079
+
4728
5080
  export type SubmitCrashesRequest = {
4729
5081
  ids: Array<string>;
4730
5082
  };
@@ -5204,11 +5556,21 @@ export type UpdateLdapConfigRequest = {
5204
5556
  admin_group_dn?: string | null;
5205
5557
  bind_dn?: string | null;
5206
5558
  bind_password?: string | null;
5559
+ /**
5560
+ * Inline PEM CA certificate/chain (migration 174, #2782). Omit to leave
5561
+ * unchanged; send an empty string to clear.
5562
+ */
5563
+ ca_certificate?: string | null;
5207
5564
  display_name_attribute?: string | null;
5208
5565
  email_attribute?: string | null;
5209
5566
  group_base_dn?: string | null;
5210
5567
  group_filter?: string | null;
5211
5568
  groups_attribute?: string | null;
5569
+ /**
5570
+ * See `CreateLdapConfigRequest::insecure_skip_verify` (migration 174,
5571
+ * #2782). Omit to leave the stored value unchanged.
5572
+ */
5573
+ insecure_skip_verify?: boolean | null;
5212
5574
  is_enabled?: boolean | null;
5213
5575
  name?: string | null;
5214
5576
  priority?: number | null;
@@ -5336,6 +5698,26 @@ export type UpdateRepositoryRequest = {
5336
5698
  * Stored in `repository_config` under `apt_release_version`.
5337
5699
  */
5338
5700
  apt_release_version?: string | null;
5701
+ /**
5702
+ * Update the keyless-sync unverified-ingest opt-in (#2569). When provided,
5703
+ * sets `curation_allow_unverified` (`false` restores the fail-closed
5704
+ * default; `true` opts into legacy unverified ingest). Omit to leave it
5705
+ * unchanged.
5706
+ */
5707
+ curation_allow_unverified?: boolean | null;
5708
+ /**
5709
+ * Default curation action when no rule matches: allow or review.
5710
+ * "block" is rejected (DB CHECK, migration 071); use block rules for
5711
+ * specific packages instead.
5712
+ *
5713
+ * The allowed set is spelled out in the schema so a generated SDK presents it
5714
+ * rather than an unconstrained string.
5715
+ */
5716
+ curation_default_action: string;
5717
+ /**
5718
+ * Enable curation-rule enforcement on this repository's proxy paths.
5719
+ */
5720
+ curation_enabled?: boolean | null;
5339
5721
  /**
5340
5722
  * Update the custom User-Agent for outbound HTTP requests to the upstream.
5341
5723
  * Only valid for remote repositories. Pass an empty string to remove.
@@ -5522,6 +5904,11 @@ export type UpsertLicensePolicyRequest = {
5522
5904
  */
5523
5905
  export type UpsertScanConfigRequest = {
5524
5906
  block_on_policy_violation?: boolean | null;
5907
+ /**
5908
+ * #2954: `'fail_open'` (default) | `'fail_closed'` for the inline proxy
5909
+ * scan-on-fetch action.
5910
+ */
5911
+ proxy_scan_action?: string | null;
5525
5912
  scan_enabled?: boolean | null;
5526
5913
  scan_on_proxy?: boolean | null;
5527
5914
  scan_on_upload?: boolean | null;
@@ -5557,6 +5944,25 @@ export type UserResponse = {
5557
5944
  username: string;
5558
5945
  };
5559
5946
 
5947
+ export type VersionResponse = {
5948
+ /**
5949
+ * The number of approved packages frozen into the snapshot.
5950
+ */
5951
+ package_count: number;
5952
+ /**
5953
+ * Whether this version's signed repodata has been published yet.
5954
+ */
5955
+ published: boolean;
5956
+ /**
5957
+ * The repository key the version belongs to.
5958
+ */
5959
+ repository: string;
5960
+ /**
5961
+ * The monotonic snapshot number (published/served under `/rpm/{key}/@N/`).
5962
+ */
5963
+ version_number: number;
5964
+ };
5965
+
5560
5966
  export type VirtualMemberPriority = {
5561
5967
  member_key: string;
5562
5968
  priority: number;
@@ -5729,6 +6135,21 @@ export type RejectReviewResponses = {
5729
6135
 
5730
6136
  export type RejectReviewResponse = RejectReviewResponses[keyof RejectReviewResponses];
5731
6137
 
6138
+ export type ReopenReviewData = {
6139
+ body: ReviewActionRequest;
6140
+ path: {
6141
+ id: string;
6142
+ };
6143
+ query?: never;
6144
+ url: '/api/v1/admin/age-gate/reviews/{id}/reopen';
6145
+ };
6146
+
6147
+ export type ReopenReviewResponses = {
6148
+ 200: AgeGateReviewResponse;
6149
+ };
6150
+
6151
+ export type ReopenReviewResponse = ReopenReviewResponses[keyof ReopenReviewResponses];
6152
+
5732
6153
  export type GetStaleArtifactsData = {
5733
6154
  body?: never;
5734
6155
  path?: never;
@@ -9458,6 +9879,80 @@ export type TriggerCurationSyncResponses = {
9458
9879
 
9459
9880
  export type TriggerCurationSyncResponse = TriggerCurationSyncResponses[keyof TriggerCurationSyncResponses];
9460
9881
 
9882
+ export type CreateCurationVersionData = {
9883
+ body?: never;
9884
+ path: {
9885
+ /**
9886
+ * Staging repository key
9887
+ */
9888
+ repo_key: string;
9889
+ };
9890
+ query?: never;
9891
+ url: '/api/v1/curation/repos/{repo_key}/versions';
9892
+ };
9893
+
9894
+ export type CreateCurationVersionErrors = {
9895
+ /**
9896
+ * No approved packages / packages need re-sync
9897
+ */
9898
+ 400: unknown;
9899
+ /**
9900
+ * Not authorized for this repo
9901
+ */
9902
+ 403: unknown;
9903
+ /**
9904
+ * Repository not found
9905
+ */
9906
+ 404: unknown;
9907
+ };
9908
+
9909
+ export type CreateCurationVersionResponses = {
9910
+ 201: VersionResponse;
9911
+ };
9912
+
9913
+ export type CreateCurationVersionResponse = CreateCurationVersionResponses[keyof CreateCurationVersionResponses];
9914
+
9915
+ export type PublishCurationVersionData = {
9916
+ body?: never;
9917
+ path: {
9918
+ /**
9919
+ * Staging repository key
9920
+ */
9921
+ repo_key: string;
9922
+ /**
9923
+ * Version number to publish
9924
+ */
9925
+ n: number;
9926
+ };
9927
+ query?: never;
9928
+ url: '/api/v1/curation/repos/{repo_key}/versions/{n}/publish';
9929
+ };
9930
+
9931
+ export type PublishCurationVersionErrors = {
9932
+ /**
9933
+ * Empty version / missing snippet / no signing key
9934
+ */
9935
+ 400: unknown;
9936
+ /**
9937
+ * Not authorized for this repo
9938
+ */
9939
+ 403: unknown;
9940
+ /**
9941
+ * Repository or version not found
9942
+ */
9943
+ 404: unknown;
9944
+ /**
9945
+ * Version already published (immutable)
9946
+ */
9947
+ 409: unknown;
9948
+ };
9949
+
9950
+ export type PublishCurationVersionResponses = {
9951
+ 200: VersionResponse;
9952
+ };
9953
+
9954
+ export type PublishCurationVersionResponse = PublishCurationVersionResponses[keyof PublishCurationVersionResponses];
9955
+
9461
9956
  export type ListCurationRulesData = {
9462
9957
  body?: never;
9463
9958
  path?: never;
@@ -9466,6 +9961,10 @@ export type ListCurationRulesData = {
9466
9961
  * Filter by staging repo
9467
9962
  */
9468
9963
  staging_repo_id?: string;
9964
+ /**
9965
+ * Filter by rule scope: `global` lists only the instance-wide baseline rules (admin-only)
9966
+ */
9967
+ scope?: string;
9469
9968
  };
9470
9969
  url: '/api/v1/curation/rules';
9471
9970
  };
@@ -13577,6 +14076,53 @@ export type GetQuarantineStatusResponses = {
13577
14076
 
13578
14077
  export type GetQuarantineStatusResponse = GetQuarantineStatusResponses[keyof GetQuarantineStatusResponses];
13579
14078
 
14079
+ export type QuarantineArtifactNowData = {
14080
+ /**
14081
+ * Optional; empty body uses the default reason
14082
+ */
14083
+ body: QuarantineNowRequest;
14084
+ path: {
14085
+ /**
14086
+ * Artifact ID
14087
+ */
14088
+ artifact_id: string;
14089
+ };
14090
+ query?: never;
14091
+ url: '/api/v1/quarantine/{artifact_id}/quarantine';
14092
+ };
14093
+
14094
+ export type QuarantineArtifactNowErrors = {
14095
+ /**
14096
+ * Malformed request body
14097
+ */
14098
+ 400: unknown;
14099
+ /**
14100
+ * Authentication required
14101
+ */
14102
+ 401: unknown;
14103
+ /**
14104
+ * Admin access required
14105
+ */
14106
+ 403: unknown;
14107
+ /**
14108
+ * Artifact not found
14109
+ */
14110
+ 404: unknown;
14111
+ /**
14112
+ * Artifact was rejected during security review
14113
+ */
14114
+ 409: unknown;
14115
+ };
14116
+
14117
+ export type QuarantineArtifactNowResponses = {
14118
+ /**
14119
+ * Artifact quarantined
14120
+ */
14121
+ 200: QuarantineActionResponse;
14122
+ };
14123
+
14124
+ export type QuarantineArtifactNowResponse = QuarantineArtifactNowResponses[keyof QuarantineArtifactNowResponses];
14125
+
13580
14126
  export type RejectQuarantinedArtifactData = {
13581
14127
  body: RejectRequest;
13582
14128
  path: {
@@ -13872,6 +14418,23 @@ export type ListArtifactsData = {
13872
14418
  * `docker_tags` array.
13873
14419
  */
13874
14420
  group_by?: string | null;
14421
+ /**
14422
+ * Opaque keyset cursor (#2520, #2519, #2518). Pass the `next_cursor`
14423
+ * value from the previous response to fetch the next page; `page` is
14424
+ * ignored while a cursor is present. Supported by the flat artifact
14425
+ * listing of hosted/local, virtual, and remote repositories (#2518,
14426
+ * #2519), by `group_by=docker_tag`, and by `group_by=maven_component`
14427
+ * on remote repositories; other listing modes ignore it.
14428
+ */
14429
+ cursor?: string | null;
14430
+ /**
14431
+ * Total-count mode for keyset-paged listings (#2520, #2519).
14432
+ * `count=exact` runs a dedicated COUNT query so `pagination.total` is
14433
+ * exact; otherwise the keyset-paged listings report a cheap lower bound
14434
+ * (rows seen so far, +1 when another page exists) and `has_more` is the
14435
+ * authoritative "is there a next page" signal.
14436
+ */
14437
+ count?: string | null;
13875
14438
  };
13876
14439
  url: '/api/v1/repositories/{key}/artifacts';
13877
14440
  };
@@ -14469,13 +15032,17 @@ export type UpdateVirtualMembersData = {
14469
15032
 
14470
15033
  export type UpdateVirtualMembersErrors = {
14471
15034
  /**
14472
- * Repository is not virtual
15035
+ * Repository is not virtual, or a member is invalid
14473
15036
  */
14474
15037
  400: unknown;
14475
15038
  /**
14476
15039
  * Authentication required
14477
15040
  */
14478
15041
  401: unknown;
15042
+ /**
15043
+ * Insufficient permissions
15044
+ */
15045
+ 403: unknown;
14479
15046
  /**
14480
15047
  * Repository not found
14481
15048
  */
@@ -14484,7 +15051,7 @@ export type UpdateVirtualMembersErrors = {
14484
15051
 
14485
15052
  export type UpdateVirtualMembersResponses = {
14486
15053
  /**
14487
- * Members updated
15054
+ * Members replaced with the supplied set
14488
15055
  */
14489
15056
  200: VirtualMembersListResponse;
14490
15057
  };
@@ -14919,6 +15486,50 @@ export type GetRepositoryStorageResponses = {
14919
15486
 
14920
15487
  export type GetRepositoryStorageResponse = GetRepositoryStorageResponses[keyof GetRepositoryStorageResponses];
14921
15488
 
15489
+ export type GetRepositoryStorageTreeData = {
15490
+ body?: never;
15491
+ path: {
15492
+ /**
15493
+ * Repository key
15494
+ */
15495
+ key: string;
15496
+ };
15497
+ query?: {
15498
+ /**
15499
+ * Folder prefix to root the listing at (`''`/absent = repository root).
15500
+ * Leading/trailing slashes are ignored.
15501
+ */
15502
+ prefix?: string | null;
15503
+ /**
15504
+ * How many tree levels below `prefix` to return (default 1 = immediate
15505
+ * children, clamped to 1..=5).
15506
+ */
15507
+ depth?: number | null;
15508
+ /**
15509
+ * Maximum number of descendant nodes returned (default 200, clamped to
15510
+ * 1..=1000). `truncated` is set when the limit cut the listing.
15511
+ */
15512
+ limit?: number | null;
15513
+ };
15514
+ url: '/api/v1/repositories/{key}/storage/tree';
15515
+ };
15516
+
15517
+ export type GetRepositoryStorageTreeErrors = {
15518
+ /**
15519
+ * Repository not found
15520
+ */
15521
+ 404: unknown;
15522
+ };
15523
+
15524
+ export type GetRepositoryStorageTreeResponses = {
15525
+ /**
15526
+ * Per-prefix storage rollup
15527
+ */
15528
+ 200: RepositoryStorageTreeResponse;
15529
+ };
15530
+
15531
+ export type GetRepositoryStorageTreeResponse = GetRepositoryStorageTreeResponses[keyof GetRepositoryStorageTreeResponses];
15532
+
14922
15533
  export type TestUpstreamData = {
14923
15534
  body?: never;
14924
15535
  path: {
@@ -18167,7 +18778,7 @@ export type RotateWebhookSecretErrors = {
18167
18778
 
18168
18779
  export type RotateWebhookSecretResponses = {
18169
18780
  /**
18170
- * Secret rotated. Body includes the new raw secret exactly once.
18781
+ * Secret rotated. Body reports success and metadata only; the raw secret is not returned.
18171
18782
  */
18172
18783
  200: RotateWebhookSecretResponse;
18173
18784
  };