Compare commits

...

854 Commits

Author SHA1 Message Date
b12fe66871 Merge branch 'main' into docs/update-net-sdk 2025-05-29 08:07:43 -07:00
28582d9134 Update .NET docs with new links 2025-05-29 08:07:07 -07:00
04908edb5b update 2025-05-29 10:28:35 -04:00
e8753a3ce8 Update 2025-05-29 10:16:59 -04:00
1947989ca5 Merge pull request #3668 from Infisical/feat/add-kubernetes-dynamic-secret
feat: add kubernetes dynamic secret
2025-05-29 21:45:22 +08:00
c22e616771 misc: addressed k8 doc changes 2025-05-29 13:34:41 +00:00
40711ac707 misc: addressed comments 2025-05-29 21:15:53 +08:00
a47e6910b1 Merge pull request #3678 from Infisical/daniel/fix-k8s-https-protocol
fix: allow https on gateway k8s hosts
2025-05-29 17:06:20 +04:00
78c4a591a9 requested changes 2025-05-29 16:57:22 +04:00
f6b7717517 fix: allow https on gateway k8s hosts 2025-05-29 16:39:47 +04:00
b21a5b6425 Merge pull request #3672 from Infisical/ENG-2843
Improved Key Schema docs + tooltip
2025-05-28 23:39:01 -04:00
66a5691ffd Merge pull request #3675 from Infisical/revert-3546-feat/point-in-time-revamp
Revert "feat(PIT): Point In Time Revamp"
2025-05-28 20:56:38 -04:00
6bdf62d453 Revert "feat(PIT): Point In Time Revamp" 2025-05-28 20:56:04 -04:00
652a48b520 Merge pull request #3674 from Infisical/revert-3671-fix/pitCheckpointCreationBatch
Revert "PIT: fix checkpoint creation to do it in batches to avoid insert fails"
2025-05-28 20:55:56 -04:00
3148c54e18 Revert "PIT: fix checkpoint creation to do it in batches to avoid insert fails" 2025-05-28 20:55:46 -04:00
bd4cf64fc6 Merge pull request #3670 from Infisical/ENG-2827
feat(secret-sharing): Require Login for Secrets Shared to Specific Emails
2025-05-28 19:23:26 -04:00
f4e3d7d576 Review fix 2025-05-28 19:22:46 -04:00
8298f9974f Improved Key Schema docs + tooltip 2025-05-28 19:18:09 -04:00
da347e96e1 Merge pull request #3671 from Infisical/fix/pitCheckpointCreationBatch
PIT: fix checkpoint creation to do it in batches to avoid insert fails
2025-05-29 00:17:33 +01:00
5df96234a0 PIT: fix checkpoint creation to do it in batches to avoid insert fails 2025-05-28 20:10:12 -03:00
e78682560c Merge pull request #3546 from Infisical/feat/point-in-time-revamp
feat(PIT): Point In Time Revamp
2025-05-28 18:24:37 -04:00
1602fac5ca PIT: decrese PIT_CHECKPOINT_WINDOW to 1 for deployment 2025-05-28 19:16:19 -03:00
0100bf7032 PIT: decrese PIT_CHECKPOINT_WINDOW to 5 for deployment 2025-05-28 19:13:28 -03:00
e2c49878c6 Merge pull request #3666 from Infisical/feat/add-token-period-support
feat: add token period support for ua
2025-05-28 17:38:59 -04:00
e74117b7fd add link to secret zero section 2025-05-28 17:32:03 -04:00
335aada941 Doc and review tweaks 2025-05-28 17:28:34 -04:00
b949fe06c3 Doc update 2025-05-28 17:25:21 -04:00
28e539c481 PIT: improve wording on the revert button 2025-05-28 17:37:44 -03:00
5c4c881b60 Docs update 2025-05-28 15:50:46 -04:00
8ffb92bfb3 Docs revamp 2025-05-28 15:39:44 -04:00
db9a1726c2 misc: doc improvments 2025-05-29 03:32:19 +08:00
15986633c7 PIT: omit commit version check on rollbacks and reverts 2025-05-28 16:07:42 -03:00
c4809bbb54 PIT: remove reminders from commit history 2025-05-28 15:51:51 -03:00
6305aab0d1 Merge branch 'main' into ENG-2827 2025-05-28 14:44:51 -04:00
456493ff5a feat(secret-sharing): Require Login for Email Sharing 2025-05-28 14:44:27 -04:00
8cfaefcec5 misc: added missing types 2025-05-29 02:43:36 +08:00
e39e80a0e7 misc: added proper propagation of error to logs 2025-05-29 02:38:14 +08:00
8cae92f29e misc: make it work with gateway 2025-05-29 02:01:17 +08:00
918911f2e4 misc: addressed greptile 2025-05-29 01:40:12 +08:00
a1aee45eb2 doc: added docs 2025-05-28 17:36:47 +00:00
5fe93dc35a Merge pull request #3669 from Infisical/update-oidc-logs
Update OIDC logs
2025-05-28 12:34:36 -04:00
5e0e7763a3 Merge pull request #3664 from Infisical/aws-secret-manager-fix
Fix: Update aws secret manager sync to handle constrained iam policies
2025-05-28 09:31:41 -07:00
f663d1d4a6 update log 2025-05-28 12:28:33 -04:00
650f6d9585 feat: add kubernetes dynamic secret 2025-05-29 00:16:01 +08:00
7994034639 Merge pull request #3660 from Infisical/misc/add-proper-notice-for-non-admin-privilege-upgrade-1
misc: added proper notice for non-admins doing privilege upgrade
2025-05-28 09:59:09 -04:00
48619ed24c Fix lint issue 2025-05-28 08:50:40 -03:00
21fb8df39b Merge branch 'feat/point-in-time-revamp' of https://github.com/Infisical/infisical into feat/point-in-time-revamp 2025-05-28 08:44:16 -03:00
f03a7cc249 PIT: add description to folder versioning 2025-05-28 08:43:32 -03:00
f2dcbfa91c misc: moved prompt to tooltip 2025-05-28 16:33:14 +08:00
d08510ebe4 misc: add proper grace period for max ttl and descriptive comment 2025-05-28 16:24:23 +08:00
767159bf8f doc: added mention of periodic token to ua section 2025-05-28 08:10:27 +00:00
98457cdb34 misc: addressed frontend lint 2025-05-28 15:40:09 +08:00
8ed8f1200d feat: add token period support for ua 2025-05-28 15:35:10 +08:00
30252c2bcb minor text updates 2025-05-28 00:06:50 -04:00
9687f33122 Merge pull request #3665 from Infisical/allow-machine-to-read-billing
Allow machine identity to read billing
2025-05-27 22:36:29 -04:00
a5282a56c9 allow machine identity to read billing 2025-05-27 22:26:32 -04:00
cc3551c417 fix: update aws secret manager sync to handle constrained iam policies 2025-05-27 18:25:20 -07:00
9e6fe39609 Merge pull request #3663 from Infisical/add-logs-for-oidc-claims
add oidc logs
2025-05-27 21:24:38 -04:00
2bc91c42a7 add oidc logs 2025-05-27 21:18:22 -04:00
c7ec825830 Improve restore buttons on the UI and reconstruct folder children on revert by default 2025-05-27 19:42:31 -03:00
5b7f445e33 PIT: fix for folder commit order on cascade deletion 2025-05-27 18:28:00 -03:00
7fe53ab00e PIT: add batch logic to initializeFolder migration 2025-05-27 11:58:17 -03:00
90c17820fc misc: added proper notice for non-admins doing privilege upgrade 2025-05-27 22:54:50 +08:00
e739b29b3c Merge pull request #3659 from akhilmhdh/feat/cloud-region-flag
feat: added region flag
2025-05-27 10:49:55 -04:00
=
1a89f2a479 feat: added missing validation 2025-05-27 19:17:06 +05:30
78568bffe2 Merge pull request #3655 from Infisical/fix/cliCustomHeadersDoc
Fix CLI custom headers doc tip
2025-05-27 13:08:46 +01:00
=
1407a122b9 feat: added region flag 2025-05-27 15:50:48 +05:30
8168b5faf8 PIT: fix resourceChangeSchema schema 2025-05-26 23:25:05 -03:00
8b9e035bf6 PIT: fix folder update issue 2025-05-26 23:08:01 -03:00
d36d0784ca PIT: Add delete commit for cascade deletion 2025-05-26 21:51:43 -03:00
e69354b546 Merge pull request #3640 from akhilmhdh/feat/redis-sentinel-support
Feat/redis sentinel support
2025-05-26 18:47:15 -04:00
64bd5ddcc8 Merge branch 'main' into feat/redis-sentinel-support 2025-05-26 18:42:12 -04:00
72088634d8 update config file 2025-05-26 18:40:31 -04:00
f3a84f6001 Merge branch 'main' into feat/point-in-time-revamp 2025-05-26 17:28:38 -03:00
13672481a8 Merge branch 'main' into feat/point-in-time-revamp 2025-05-26 17:14:30 -03:00
058394f892 Merge pull request #3583 from Infisical/feat/acme-and-external-ca
feat: acme and external CA for PKI
2025-05-27 03:47:36 +08:00
c623c615a1 Fix lint issue 2025-05-26 14:52:04 -03:00
034a8112b7 Merge branch 'main' into feat/point-in-time-revamp 2025-05-26 14:42:55 -03:00
5fc6fd71ce Fix tag and metadata insert/update logic on revert/rollback and fix tree checkpoint logic to exclude reserved folders 2025-05-26 14:31:05 -03:00
be37e27dbf Merge pull request #3647 from Infisical/ENG-2814
feat(secret-sync): 1Password Secret Sync + App Connection
2025-05-26 11:56:56 -04:00
3b62f956e9 Merge pull request #3656 from akhilmhdh/feat/org-id-logger
feat: added missing memberused, identityused in getplan for cloud
2025-05-26 11:32:52 -04:00
=
f49e3788cc feat: added missing memberused, identityused in getplan 2025-05-26 20:59:57 +05:30
1147f87eed lint fixes 2025-05-26 10:56:53 -04:00
995e3254ba comment fix 2025-05-26 10:41:21 -04:00
67d0c53912 Merge 2025-05-26 10:39:51 -04:00
a6fbcb3e01 Merge pull request #3654 from Infisical/approvals-redesign
improve change requests design
2025-05-26 10:35:47 -04:00
db1ca2b89f Merge pull request #3643 from Infisical/ENG-2801
feat(policies): Approval Request Break-Glass Bypass
2025-05-26 10:29:21 -04:00
f91bbe1f31 Merge remote-tracking branch 'origin/main' into feat/acme-and-external-ca 2025-05-26 21:33:23 +08:00
e5f475e8d6 Fix type and lint issues 2025-05-26 09:16:10 -03:00
1e4ca2f48f Fix CLI custom headers doc tip 2025-05-26 08:50:28 -03:00
8d5e7406c3 improve change requests design 2025-05-25 15:53:30 -07:00
3b230dad9a Merge pull request #3653 from akhilmhdh/feat/org-id-logger
feat: small patch on license
2025-05-25 13:38:39 -04:00
=
782bf2cdc9 feat: resolved count fallback 2025-05-25 22:35:16 +05:30
=
982b506eb8 feat: small patch on license 2025-05-25 22:29:12 +05:30
e5bc609a2a PIT: add last commit indicator and remove unnecessary empty folder commit 2025-05-25 12:07:00 -03:00
b812761bdd PIT: hide restore button for last commit 2025-05-25 11:52:28 -03:00
14362dbe6a PIT: general improvements and fixes 2025-05-25 11:00:06 -03:00
b7b90aea33 PIT: general improvements and fixes 2025-05-25 00:12:31 -03:00
8d147867ed Merge pull request #3652 from Infisical/ENG-2817
Update docs and some UI to make Admin SSO bypass more clear
2025-05-24 01:30:07 -04:00
eb4e727922 Update overview.mdx 2025-05-24 01:29:38 -04:00
bb276a0dba review fixes 2025-05-24 01:25:49 -04:00
7cdb015b81 Merge pull request #3633 from Infisical/ENG-2807
feat(secret-sync): Move OCI Vault Sync + OCI App Connection to enterprise
2025-05-23 20:38:53 -04:00
ce446fa723 Small out-of-scope greptile fixes 2025-05-23 20:29:34 -04:00
82f6c9fb58 UI tweaks 2025-05-23 20:18:05 -04:00
6369d13862 Update docs and some UI to make Admin SSO bypass more clear 2025-05-23 18:47:33 -04:00
9f91970be2 Merge pull request #3651 from Infisical/debug-verify-email-log
debug: Add log to help debug verify loop
2025-05-23 15:04:08 -07:00
c7398d924a improvement: make log more cloudwatch friendly 2025-05-23 15:01:09 -07:00
df57364985 ui fix 2025-05-23 17:59:29 -04:00
84322f4f68 temp: add log to help debug verify loop 2025-05-23 14:10:04 -07:00
5518df116f Merge pull request #3617 from Infisical/ENG-2797
feat(audit-logs): Audit org updates, project create / update / delete
2025-05-23 13:41:54 -04:00
73c6c076e8 Review fixes 2025-05-23 13:18:56 -04:00
ba2a772247 Merge branch 'main' into ENG-2797 2025-05-23 13:13:43 -04:00
8fbe46256b Merge pull request #3649 from Infisical/ENG-2820
feat(smtp-service): Custom CA Certs
2025-05-23 13:10:03 -04:00
b75bb93d83 Describe fix 2025-05-23 13:08:15 -04:00
db4db04ba6 Doc updates 2025-05-23 13:02:04 -04:00
db44d958d3 Base64 example for docs 2025-05-23 12:41:58 -04:00
12beb06682 Swap to using base64 2025-05-23 12:33:31 -04:00
804f8be07d Review fixes:
- Review envName from endpoint params and derive it
- Use variables in logic blocks
- New function on frontend + memoization
2025-05-23 12:05:38 -04:00
e81991c545 Merge branch 'main' into ENG-2801 2025-05-23 11:18:45 -04:00
28a3bf0b94 Improvement on createCommit function to add changes in batches 2025-05-23 10:59:05 -03:00
5712c24370 Fix migration to initialize pit projects 2025-05-23 10:45:39 -03:00
65bc522ae9 feat(smtp-service): Custom CA Certs 2025-05-23 03:19:45 -04:00
b950e07ad6 fixed firefox bug 2025-05-23 02:06:05 -04:00
498bf8244c Merge branch 'main' into ENG-2807 2025-05-23 01:51:06 -04:00
4a391c7ac2 PIT: add commits to snapshots and improve old role hidding 2025-05-23 01:46:13 -03:00
d49c1e4b72 greptile review fixes 2025-05-22 20:41:35 -04:00
424e4670e5 Merge pull request #3646 from akhilmhdh/feat/org-id-logger
feat: org id logger
2025-05-22 17:11:21 -07:00
5e803e76d7 lint 2025-05-22 20:00:02 -04:00
6648397a64 docs 2025-05-22 19:57:15 -04:00
85edbbcdc3 add org id to missing auth modes 2025-05-22 16:29:40 -07:00
a64f8ac776 feat(secret-sync): 1Password Secret Sync 2025-05-22 17:51:09 -04:00
=
b46a0dfc21 feat: org id logger 2025-05-23 02:03:14 +05:30
95ef113aea doc: updated subscriber and external ca 2025-05-22 19:45:34 +00:00
07bf65b1c3 doc: add external CA doc with reference to Acme CA 2025-05-22 19:28:21 +00:00
12071e4816 misc: updated renewal unit UI 2025-05-23 02:51:09 +08:00
a40d4efa39 misc: updated repeat schedule for auto renewal 2025-05-23 01:28:53 +08:00
6d509d85f4 feat(app-connections): 1Password App Connection 2025-05-22 13:13:47 -04:00
5b200f42a3 misc: update audit logs 2025-05-23 01:01:14 +08:00
64f724ed95 feat: added subscriber cert auto-renewal 2025-05-23 00:53:50 +08:00
b0d5be6221 Merge pull request #3637 from Infisical/ENG-2803
feat(frontend): Persist "perPage" for tables
2025-05-22 12:38:52 -04:00
2b21c9d348 Fix for secret-sync import secrets creating a new version for secrets that did not change 2025-05-22 13:02:38 -03:00
f0a45fb7d8 Review fixes 2025-05-22 11:32:49 -04:00
40398efb06 Merge branch 'main' into ENG-2803 2025-05-22 11:19:29 -04:00
a16c1336fc Merge pull request #3645 from Infisical/fix/secretInputSelectAllFix
Only select all secret value on edit but no view permissions, and keep the select until user starts writting
2025-05-22 12:01:20 -03:00
ef4df9691d Fix license-fns test changes 2025-05-22 11:46:43 -03:00
6a23583391 Only select all secret value on edit but no view permissions, and keep the select until user starts writting 2025-05-22 11:41:35 -03:00
e8d00161eb misc: addressed lint 2025-05-22 21:48:03 +08:00
0a5a073db1 Merge remote-tracking branch 'origin/main' into feat/acme-and-external-ca 2025-05-22 21:35:20 +08:00
0f14685d54 misc: updated doc title 2025-05-22 13:33:15 +00:00
d5888d5bbb misc: updated docs based on review 2025-05-22 13:31:00 +00:00
8ff95aedd5 misc: addressed CA status issue 2025-05-22 20:04:21 +08:00
2b948a18f3 Type fixes and PIT history pagination 2025-05-21 23:43:41 -03:00
4d173ad163 ui and backend improvements 2025-05-21 19:46:47 -04:00
7041b88b9d license revert 2025-05-21 18:44:08 -04:00
f06004370d PIT: address PR suggestions 2025-05-21 19:42:09 -03:00
c1fa344f02 Greptile review fixes 2025-05-21 18:17:01 -04:00
df75b3b8d3 misc: migrated internal CA to use new CA endpoint 2025-05-22 04:21:54 +08:00
e0322c8a7f Merge pull request #3642 from Infisical/misc/add-proper-error-for-bypass-failure
misc: add proper error message for bypass failure
2025-05-21 13:06:21 -07:00
e3725dd3ab merge + final tweaks 2025-05-21 15:46:36 -04:00
dc6a94ccda Merge branch 'main' into ENG-2801 2025-05-21 15:02:21 -04:00
e5229a5377 access request bypass 2025-05-21 15:01:54 -04:00
2e8003ca95 Merge pull request #3628 from Infisical/ENG-2800
feat(policies): Specific permission for bypassing policy
2025-05-21 14:48:36 -04:00
=
04989372b1 feat: resolved ts issue 2025-05-21 22:55:15 +05:30
d185dbb7ff misc: add proper error message for bypass failure 2025-05-22 01:00:13 +08:00
77de085ffc misc: addressed first set of review comments 2025-05-22 00:22:49 +08:00
afcae17e91 Merge pull request #3639 from Infisical/increase-slug-schema
increase name sizes
2025-05-21 08:13:32 -07:00
=
c985690e9a feat: reptile review changes 2025-05-21 20:11:59 +05:30
=
bb2a70b986 feat: updated doc 2025-05-21 20:01:13 +05:30
=
3ac3710273 feat: added sentinel suppor for backend 2025-05-21 20:01:04 +05:30
=
92cb034155 feat: added sentinel sink 2025-05-21 20:00:38 +05:30
2493bbbc97 PIT: fix blocker for deep rollbacks 2025-05-21 09:08:12 -03:00
77b42836e7 Merge remote-tracking branch 'origin/main' into feat/acme-and-external-ca 2025-05-21 19:21:12 +08:00
949615606f misc: moved external pki migration to latest along with column changes 2025-05-21 19:07:20 +08:00
6cd7657e41 lint 2025-05-21 02:44:16 -04:00
38bf5e8b1d increase name sizes 2025-05-21 02:36:10 -04:00
4292cb2a04 Merge pull request #3518 from akhilmhdh/fix/email-ambigious
fix: email casing conflicts
2025-05-20 21:16:16 -07:00
051f53c66e Update bug-bounty.mdx 2025-05-20 18:15:36 -07:00
a6bafb8adc feat(frontend): Persisnt "perPage" for tables 2025-05-20 19:42:32 -04:00
99daa43fc6 delete duplicate accounts 2025-05-20 16:40:21 -07:00
e9e1f4ff5d final touches 2025-05-20 16:53:58 -04:00
13afc9c996 Merge branch 'main' into ENG-2797 2025-05-20 16:48:28 -04:00
67d4da40ec review fixes 2025-05-20 16:48:24 -04:00
27badad3d7 Merge pull request #3614 from Infisical/ldap-target-principal-rotation
feature(secret-rotation): Add support for LDAP target principal self-rotation and UPN
2025-05-20 12:56:52 -07:00
b5e3af6e7d Merge pull request #3636 from Infisical/helm-update-v0.9.3
Update Helm chart to version v0.9.3
2025-05-20 23:55:21 +04:00
280fbdfbb9 Update Helm chart to version v0.9.3 2025-05-20 19:54:55 +00:00
18fc10aaec Merge pull request #3635 from Infisical/daniel/k8s-generator-fix
fix(k8s): disable clustergenerator watching in namespace scoped installations
2025-05-20 23:52:43 +04:00
b20e04bdeb improvements: address feedback 2025-05-20 12:41:37 -07:00
10d14edc20 Update infisicalpushsecret_controller.go 2025-05-20 23:35:43 +04:00
4abdd4216b Merge pull request #3634 from akhilmhdh/feat/license-server-changes
Feat: license server changes
2025-05-20 12:14:43 -07:00
=
332ed68c13 feat: updated message based on feedback 2025-05-21 00:42:06 +05:30
52feabd786 fix(k8s): disable clustergenerator watching in namespace scoped installation 2025-05-20 23:03:58 +04:00
=
d7a99db66a feat: corrected to small subset of error status code 2025-05-21 00:29:36 +05:30
=
fc0bdc25af feat: corrected text 2025-05-21 00:26:02 +05:30
ec633c3e3d greptile review fixes 2025-05-20 14:52:52 -04:00
=
5ffe45eaf5 feat: fixed license server changes in cloud 2025-05-21 00:21:27 +05:30
=
8f795100ea feat: updated cloud functions for quantity change made 2025-05-21 00:21:27 +05:30
1efdb31037 app connection + finishing touches 2025-05-20 13:25:15 -04:00
8d8a3efd77 Merge pull request #3631 from Infisical/daniel/password-resets-fix
fix(password-resets): allow password resets when users don't have a password set
2025-05-20 18:14:07 +04:00
44aa743d56 Type fixes 2025-05-20 11:09:25 -03:00
fefb71dd86 Merge branch 'main' into feat/point-in-time-revamp 2025-05-20 10:52:20 -03:00
677180548b Update auth-password-service.ts 2025-05-20 17:47:47 +04:00
1748052cb0 Merge branch 'main' into feat/point-in-time-revamp 2025-05-20 10:37:41 -03:00
293bea474e Merge pull request #3626 from Infisical/daniel/agent-injector-docs
docs: k8s agent injector
2025-05-20 17:33:15 +04:00
bc4fc9a1ca docs: injector diagram 2025-05-20 17:20:54 +04:00
483850441d Update kubernetes-injector.mdx 2025-05-20 16:58:19 +04:00
4355fd09cc requested changes 2025-05-20 16:57:11 +04:00
1f85d9c486 Merge pull request #3629 from Infisical/misc/add-fortanix-hsm
misc: add docs for Fortanix HSM
2025-05-20 20:51:13 +08:00
c01a98ccf1 Merge pull request #3555 from Infisical/feat/point-in-time-revamp-2710
Feat/point in time revamp 2710
2025-05-20 09:46:08 -03:00
9ea9f90928 PIT: add envID to rollback endpoint 2025-05-20 09:34:43 -03:00
6319f53802 PIT: UI views 2025-05-20 08:22:14 -03:00
75d33820b3 Merge pull request #3630 from Infisical/daniel/agent-exit-code
fix(agent): exit code 1 on fetch secrets error
2025-05-20 14:39:34 +04:00
074446df1f Update agent.go 2025-05-20 14:32:07 +04:00
7ffa0ef8f5 Update deployment.yaml 2025-05-20 12:36:14 +04:00
5250e7c3d5 Update docs/documentation/platform/kms/hsm-integration.mdx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-20 12:34:57 +04:00
2deaa4eff3 misc: final revisions 2025-05-20 06:14:15 +00:00
0b6bc4c1f0 update spend 2025-05-19 21:58:19 -07:00
966294bd0e move OCI Vault Secret Sync to EE 2025-05-19 23:33:58 -04:00
e1dee0678e lint fix 2025-05-19 21:42:25 -04:00
8b25f202fe feat(policies): Specific permission for bypassing policy 2025-05-19 21:28:18 -04:00
abbe7bbd0c Merge pull request #3627 from Infisical/fix-breaking-schema-changes--for-k8s
Allow Hyphens in k8s
2025-05-19 18:26:09 -07:00
565340dc50 fix lint 2025-05-19 18:13:45 -07:00
36c428f152 allow hyphens in host name 2025-05-19 17:45:12 -07:00
f97826ea82 allow hyphens in host name 2025-05-19 17:42:42 -07:00
0f5cbf055c remove limit 2025-05-19 17:27:47 -07:00
1345ff02e3 docs: k8s agent injector 2025-05-20 01:54:17 +04:00
b960ee61d7 Merge pull request #3624 from Infisical/product-select-docs
add product select to docs + change the heading
2025-05-19 17:16:38 -04:00
0b98a214a7 ui tweaks 2025-05-19 17:15:42 -04:00
599c2226e4 Merge pull request #3615 from Infisical/ENG-2787
feat(org): Shared Secret limits for org
2025-05-19 16:26:10 -04:00
8e24a4d3f8 misc: added docs 2025-05-19 20:19:39 +00:00
27486e7600 Merge pull request #3625 from Infisical/ENG-2795
fix secret rollback not tainting form
2025-05-19 16:17:26 -04:00
979e9efbcb fix lint issue 2025-05-19 15:52:50 -04:00
e06b5ecd1b misc: add error handling for already initialized error 2025-05-20 03:44:21 +08:00
1097ec64b2 ui improvements 2025-05-19 15:40:07 -04:00
93fe9929b7 fix secret rollback not tainting form 2025-05-19 15:22:24 -04:00
aca654a993 Update docs/documentation/platform/organization.mdx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-19 13:38:34 -04:00
b5cf237a4a add product select to docs + change the heading 2025-05-19 13:35:35 -04:00
6efb630200 Moved secret share limits to secret share settings 2025-05-19 12:32:22 -04:00
151ede6cbf Merge 2025-05-19 12:20:02 -04:00
931ee1e8da Merge pull request #3616 from Infisical/ENG-2783
feat(secret-sharing): Specify Emails
2025-05-19 12:12:07 -04:00
0401793d38 Changed "token" param to "hash" and used hex encoding for URL 2025-05-19 10:48:58 -04:00
eb31318d39 misc: corrected direct issuance checks for CAs 2025-05-19 21:06:13 +08:00
7f6dcd3afa Merge remote-tracking branch 'origin/main' into feat/acme-and-external-ca 2025-05-19 20:11:48 +08:00
2b4a6ad907 misc: addressed review comments 2025-05-19 20:08:43 +08:00
0613c12508 Merge pull request #3618 from Infisical/fix-bundle-for-old-certs 2025-05-18 13:29:31 -04:00
ba8fcb6891 Merge branch 'feat/acme-and-external-ca' of https://github.com/Infisical/infisical into feat/acme-and-external-ca 2025-05-18 23:57:38 +08:00
c2df8cf869 misc: allow wildcard support for SAN 2025-05-18 23:57:17 +08:00
e383872486 Merge branch 'feat/acme-and-external-ca' of https://github.com/Infisical/infisical into feat/acme-and-external-ca 2025-05-18 15:41:07 +00:00
490c589a44 misc: updated doc reference urls 2025-05-18 15:40:20 +00:00
b358f2dbb7 feat: added subscriber endpoint for fetching active cert 2025-05-18 23:37:23 +08:00
10ed6f6b52 misc: finalized descriptions and api reference 2025-05-18 22:22:00 +08:00
e0f1311f6d doc: added docs for external CA 2025-05-18 13:31:36 +00:00
60d3ffac5d Merge pull request #3620 from Infisical/daniel/k8s-auth-fix
fix(identities-auth): fixed kubernetes auth login
2025-05-17 22:18:52 +04:00
5e192539a1 Update identity-kubernetes-auth-service.ts 2025-05-17 22:13:49 +04:00
021a8ddace Update identity-kubernetes-auth-service.ts 2025-05-17 22:06:51 +04:00
f92aba14cd Merge pull request #3619 from Infisical/fix-padding
Org Products Padding Fix
2025-05-17 13:11:56 -04:00
fdeefcdfcf padding to match similar container 2025-05-17 13:10:15 -04:00
645f70f770 tweaks 2025-05-17 13:05:09 -04:00
923feb81f3 fix bundle endpoint for old certs 2025-05-17 12:44:05 -04:00
1cff92d000 misc: added type assertion 2025-05-18 00:41:27 +08:00
db8f43385d misc: addressed undefined issue 2025-05-18 00:27:52 +08:00
41b45c212d misc: addressed lint issue 2025-05-18 00:17:38 +08:00
ef9269fe10 misc: addressed type issue with date fields 2025-05-18 00:07:03 +08:00
4d95052896 misc: add indicators for errors 2025-05-17 23:52:20 +08:00
260679b01d misc: addressed type 2025-05-17 22:39:43 +08:00
a77cc77be8 explicitly pass values 2025-05-17 03:15:22 -04:00
9bc5c55cd0 revert license 2025-05-17 03:03:44 -04:00
2cbad206b5 feat(audit-logs): Audit org updates, project create / update / delete 2025-05-17 03:02:33 -04:00
16c51af340 review fixes 2025-05-17 02:17:41 -04:00
9fd37ca456 greptile review fixes 2025-05-17 01:51:05 -04:00
56b7328231 misc: addressed type issue and ux improvements 2025-05-17 13:00:04 +08:00
92bebf7d84 feat(secret-sharing): Specify Emails 2025-05-17 00:54:40 -04:00
df053bbae9 Merge pull request #3611 from Infisical/ENG-2782
feat(project): Enable / Disable Secret Sharing
2025-05-16 18:58:39 -04:00
42319f01a7 greptile review fixes 2025-05-16 18:54:57 -04:00
0ea9f9b60d feat(org): Shared Secret limits for org 2025-05-16 18:36:02 -04:00
33ce783fda improvements: address feedback 2025-05-16 15:16:36 -07:00
63c48dc095 feature: add suport for target principal self rotation 2025-05-16 13:15:33 -07:00
edefa7698c misc: addressed comments 2025-05-17 03:42:49 +08:00
16eefe5bac Merge pull request #3610 from Infisical/sso-empty-state
improvement(sso-page): Add empty display for SSO general tab if no SSO is enabled
2025-05-16 10:10:16 -07:00
b984111a73 Merge pull request #3612 from Infisical/daniel/cli-auth-fix
fix(auth): cli auth bug
2025-05-16 17:29:21 +04:00
677ff62b5c fix(auth): cli auth bug 2025-05-16 17:22:18 +04:00
60ea4bb579 Merge branch 'ENG-2661' into feat/acme-and-external-ca 2025-05-16 21:01:32 +08:00
8cc2e08f24 fix(auth): cli auth bug 2025-05-16 16:58:01 +04:00
04d553f052 misc: moved cert issuance to job 2025-05-16 20:38:08 +08:00
d90178f49a Merge pull request #3590 from Infisical/daniel/k8s-auth-gateway
feat(gateway): gateway support for identities
2025-05-16 00:10:16 -07:00
ad50cff184 Update frontend/src/pages/secret-manager/SettingsPage/components/SecretSharingSection/SecretSharingSection.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-16 00:21:30 -04:00
8e43d2a994 feat(project): Enable / Disable Secret Sharing 2025-05-16 00:08:55 -04:00
7074fdbac3 Merge pull request #3609 from Infisical/ENG-2736
feat(org-settings): Option to hide certain products from the sidebar
2025-05-15 23:24:14 -04:00
ef70de1e0b fix: add noopenner to doc link 2025-05-15 20:05:56 -07:00
7e9ee7b5e3 fix: add empty display for sso general tab if no sso is enabled 2025-05-15 20:01:08 -07:00
517c613d05 migration fix 2025-05-15 22:50:09 -04:00
ae8cf06ec6 greptile review fixes 2025-05-15 21:05:39 -04:00
818778ddc5 Update frontend/src/pages/organization/SettingsPage/components/OrgProductSelectSection/OrgProductSelectSection.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-15 21:01:46 -04:00
2e12d9a13c Update frontend/src/pages/organization/SettingsPage/components/OrgGeneralTab/OrgGeneralTab.tsx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-15 21:01:30 -04:00
e678c9d1cf remove comments 2025-05-15 20:49:01 -04:00
da0b07ce2a added the other two products and small UI tweaks 2025-05-15 20:45:32 -04:00
3306a9ca69 Merge pull request #3608 from Infisical/key-schema-tweak
allow underscores in key schema
2025-05-15 18:55:45 -04:00
e9af34a6ba Merge pull request #3607 from Infisical/key-schema-doc-tweaks
feat(docs): Key Schema Tweaks
2025-05-15 15:51:23 -07:00
3de8ed169f allow underscores in key schema 2025-05-15 18:49:30 -04:00
d1eb350bdd Merge pull request #3606 from Infisical/oidc-groups-claim-handle-string
improvement(oidc-group-membership-mapping): Update OIDC group claims to handle single group string
2025-05-15 14:47:46 -07:00
0c1ccf7c2e fix: update oidc group claims to handle single group string 2025-05-15 14:39:07 -07:00
d268f52a1c small ui tweak 2025-05-15 16:50:37 -04:00
c519cee5d1 frontend 2025-05-15 16:32:57 -04:00
6d10afc9d2 feat: POC for ACME done 2025-05-16 02:58:05 +08:00
b55a39dd24 Merge pull request #3604 from Infisical/misc/add-identity-support-for-audit-log-retention
misc: add identity support for audit log retention
2025-05-15 09:25:49 -07:00
7b880f85cc misc: add identity support for audit log retention 2025-05-15 16:19:47 +00:00
c7dc595e1a doc overview update 2025-05-15 12:05:06 -04:00
6e494f198b Merge pull request #3603 from Infisical/fix-oci-machine-identity
fix oci machine identity
2025-05-15 11:42:58 -04:00
e1f3eaf1a0 Comment for regex 2025-05-15 11:41:00 -04:00
be26dc9872 requested changes 2025-05-15 16:55:36 +04:00
aaeb6e73fe requested changes 2025-05-15 16:06:20 +04:00
1e11702c58 remove unused import 2025-05-15 01:17:38 -04:00
3b81cdb16e fix oci machine identity 2025-05-15 01:12:33 -04:00
6584166815 Merge pull request #3598 from Infisical/ENG-2755
feat(secret-sync): Secret Key Schema
2025-05-14 23:57:18 -04:00
827cb35194 review fixes 2025-05-14 23:52:05 -04:00
89a6a0ba13 Merge pull request #3602 from Infisical/general-oidc-group-mapping-docs
docs(oidc-group-membership-mapping): Add general OIDC group membership mapping documentation
2025-05-14 16:25:26 -07:00
3b9a50d65d improvements: address feedback 2025-05-14 16:20:50 -07:00
beb7200233 fix: correct overview image links 2025-05-14 14:29:46 -07:00
18e3d132a2 documentation: add general oidc group membership mapping documentation 2025-05-14 14:22:35 -07:00
c2949964b3 misc: added route for acme 2025-05-15 04:18:01 +08:00
=
52f8c6adba feat: updated ui 2025-05-15 00:56:53 +05:30
=
3d2b2cbbab feat: updated logic to have login sso 2025-05-15 00:56:53 +05:30
=
1a82809bd5 fix: resolved lint issue 2025-05-15 00:56:53 +05:30
=
c4f994750d feat: removed merge logic as we now have duplicate fix logic 2025-05-15 00:56:53 +05:30
=
fa7020949c feat: resolve alignment issue and fixed sanitization to top level 2025-05-15 00:56:53 +05:30
=
eca2b3ccde feat: rabbit and reptile feedback changes 2025-05-15 00:56:53 +05:30
=
67fc16ecd3 feat: updated frontend for casing deletion process fix 2025-05-15 00:56:53 +05:30
=
f85add7cca feat: implemented backend updates for email casing issue 2025-05-15 00:56:52 +05:30
3f74d3a80d update import 2025-05-14 13:49:25 -04:00
4a44dc6119 format a frontend file 2025-05-14 13:45:45 -04:00
dd4bc4bc73 more doc tweaks 2025-05-14 13:43:23 -04:00
6188de43e4 Merge pull request #3574 from Infisical/ENG-2706
feat(machine-identities): oracle cloud machine identity auth
2025-05-14 12:56:16 -04:00
36310387e0 Update oci-auth.mdx 2025-05-14 20:44:41 +04:00
43f3960225 Merge branch 'main' into ENG-2706 2025-05-14 12:35:17 -04:00
2f0a442866 Merge pull request #3573 from Infisical/duplicate-project-roles
feature(project/org-roles): Add ability to duplicate org and project roles
2025-05-14 09:23:02 -07:00
7e05bc86a9 improvement: address feedback 2025-05-14 08:58:29 -07:00
b0c4fddf86 review fixes 2025-05-14 11:23:12 -04:00
6faad102e2 misc: added internal CA route 2025-05-14 23:10:10 +08:00
f5578d39a6 Merge pull request #3597 from Infisical/linux-upgrade-docs
add linux upgrade docs
2025-05-14 07:45:01 -07:00
8bfd3913da PIT: add backend logic for deep PIT and rollback 2025-05-14 10:26:41 -03:00
cd028ae133 Update 20250212191958_create-gateway.ts 2025-05-14 16:01:07 +04:00
63c71fabcd fix: migrate project gateway 2025-05-14 16:00:27 +04:00
e90166f1f0 Merge branch 'heads/main' into daniel/k8s-auth-gateway 2025-05-14 14:26:05 +04:00
d1e5ae2d85 misc: updated pki collection lst 2025-05-14 14:45:24 +08:00
5a3fbc0401 Merge pull request #3599 from Infisical/misc/updated-custom-cert-to-be-crt-formawt
misc: update custom cert to be crt format for docs
2025-05-14 14:24:29 +08:00
7c52e000cd misc: update custom cert to be crt format for docs 2025-05-14 14:12:08 +08:00
cccd4ba9e5 doc changes and other tweaks 2025-05-14 01:32:09 -04:00
63f0f8e299 final release 2025-05-14 01:16:42 -04:00
c8a3837432 refine docs 2025-05-13 22:02:49 -07:00
2dd407b136 Merge pull request #3596 from Infisical/pulumi-documentation-update
Adding Pulumi documentation
2025-05-13 22:21:33 -06:00
4e1a5565d8 add linux upgrade docs 2025-05-13 20:40:29 -07:00
bae62421ae with stripSchema and filterForSchema 2025-05-13 23:08:54 -04:00
d397002704 Update pulumi.mdx 2025-05-13 20:29:06 -06:00
f5b1f671e3 Update pulumi.mdx 2025-05-13 20:17:23 -06:00
0597c5f0c0 Adding Pulumi documentation 2025-05-13 20:14:08 -06:00
eb3afc8034 Merge pull request #3595 from Infisical/remove-legacy-native-integrations-notice
improvement(native-integrations): Remove legacy badge/banner from native integrations UI
2025-05-13 18:51:03 -07:00
b67457fe93 chore: remove unused imports 2025-05-13 18:46:53 -07:00
75abdbe938 remove legacy badge/banner from native integrations UI 2025-05-13 18:41:14 -07:00
9b6a315825 Merge pull request #3593 from Infisical/ENG-2742
Fixed project roles not being editable in some cases
2025-05-13 17:10:23 -04:00
13b2f65b7e lint fix 2025-05-13 16:51:05 -04:00
6cf1e046b0 Fixed project roles not being editable in some cases 2025-05-13 16:38:26 -04:00
e5555ffd3f misc: addressed cert issuance restriction update 2025-05-14 04:20:00 +08:00
6b95bb0ceb misc: continued migration to new ca structure 2025-05-14 04:08:57 +08:00
f6e1441dc0 Merge pull request #3570 from Infisical/policy-templates
feature(project-roles): Project Role Templates
2025-05-13 12:47:40 -07:00
7ed96164e5 improvement: address feedback 2025-05-13 12:25:24 -07:00
9eeb72ac80 fix: correct import 2025-05-13 12:18:35 -07:00
f6e566a028 merge main 2025-05-13 12:10:49 -07:00
a34c74e958 Merge pull request #3580 from Infisical/feat/return-metadata-with-identity-create
Return metadata with identity post endpoints
2025-05-13 14:22:34 -04:00
eef7a875a1 Merge pull request #3585 from Infisical/ENG-2748
feat(docs): Self approval
2025-05-13 14:05:59 -04:00
09938a911b nit fix 2025-05-13 13:58:52 -04:00
af08c41008 Merge pull request #3567 from Infisical/ENG-2636
feat(secret-sync): OCI Vault
2025-05-13 13:25:11 -04:00
443c8854ea Merge branch 'main' into ENG-2636 2025-05-13 13:16:59 -04:00
f7a25e7601 Merge pull request #3592 from Infisical/lint-fix
lint fix
2025-05-13 13:16:06 -04:00
4c6e5c9c4c lint fix 2025-05-13 13:11:20 -04:00
98a4e6c96d Merge pull request #3591 from akhilmhdh/fix/ui-skew
feat: added new cache control for index html
2025-05-13 12:30:50 -04:00
b0e25a8bd1 Merge remote-tracking branch 'origin/main' into feat/acme-and-external-ca 2025-05-14 00:06:40 +08:00
c93ce06409 Merge pull request #3589 from Infisical/misc/updated-org-delete-flow
misc: updated org delete flow to clear session
2025-05-13 11:41:09 -04:00
=
672e4baec4 feat: added new cache control for index html 2025-05-13 21:03:15 +05:30
d483e70748 review fixes 2025-05-13 10:44:28 -04:00
8adf4787b9 Update 20250513081738_remove-gateway-project-link.ts 2025-05-13 15:31:13 +04:00
a12522db55 requested changes 2025-05-13 15:18:23 +04:00
49ab487dc2 Update organization-permissions.mdx 2025-05-13 15:04:21 +04:00
daf0731580 feat(gateways): decouple gateways from projects 2025-05-13 14:59:58 +04:00
4b94848a79 Merge remote-tracking branch 'origin/main' into ENG-2661 2025-05-13 16:35:42 +08:00
b5ef2a6837 Merge pull request #3569 from Infisical/pki-subscriber
Infisical PKI: Subscriber Functionality
2025-05-13 16:34:05 +08:00
879b12002c Merge remote-tracking branch 'origin/main' into ENG-2661 2025-05-13 16:24:55 +08:00
9c611daada misc: updated org delete flow to clear session 2025-05-13 16:09:26 +08:00
71edb08942 Merge pull request #3587 from Infisical/ENG-2763
Fix approval request ordering
2025-05-12 23:54:27 -04:00
89d8261a43 Fix approval request ordering 2025-05-12 23:13:57 -04:00
a2b2b07185 Merge pull request #3584 from Infisical/sso-page
Improvements(org-settings): Refactor Organization Security Settings to SSO Page
2025-05-12 18:43:35 -07:00
76864ababa fix: correct doc casing 2025-05-12 18:37:05 -07:00
52858dad79 Update docs/documentation/platform/pr-workflows.mdx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-12 21:07:57 -04:00
1d7a6ea50e Update docs/documentation/platform/pr-workflows.mdx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-12 21:07:34 -04:00
c031233247 feat(docs): Self approval 2025-05-12 21:04:05 -04:00
d17d40ebd9 improvements: refactor org security settings tab to sso page and update doc images 2025-05-12 17:18:40 -07:00
70fff1f2da review fixes 2025-05-12 19:38:00 -04:00
3f8eaa0679 remove schema change 2025-05-12 18:13:14 -04:00
50d0035d7b fix: correct remove oci secret if secret value is empty logic 2025-05-12 14:56:13 -07:00
9743ad02d5 Fix lint issues 2025-05-12 14:56:00 -07:00
50f5248e3e Merge branch 'main' into feat/return-metadata-with-identity-create 2025-05-12 17:50:13 -04:00
8d7b573988 final reviews 2025-05-12 17:39:29 -04:00
26d0ab1dc2 Fix lint issues 2025-05-12 14:34:14 -07:00
bc93db8603 misc: initial setup 2025-05-13 05:02:15 +08:00
4acdbd24e9 remove useless schema 2025-05-12 16:50:47 -04:00
c3c907788a review fixes 2025-05-12 16:42:48 -04:00
bf833a57cd Fix merge conflicts 2025-05-12 12:59:54 -07:00
e8519f6612 Revise PR based on review 2025-05-12 12:56:56 -07:00
0b4675e7b5 Merge branch 'main' into ENG-2636 2025-05-12 14:56:01 -04:00
091e521180 review fixes 2025-05-12 14:49:45 -04:00
07df6803a5 Merge pull request #3581 from Infisical/daniel/unblock-dev
fix: move cli install to aws
2025-05-12 18:54:55 +04:00
d5dbc7d7e0 erge branch 'daniel/unblock-dev' into ENG-2706 2025-05-12 10:52:40 -04:00
a09d0e8948 fix: move cli install to aws 2025-05-12 18:47:02 +04:00
c43a87947f merge fixes 2025-05-12 10:29:52 -04:00
0af9415aa6 Merge branch 'main' into ENG-2706 2025-05-12 10:18:33 -04:00
fb2b64cb19 feat(identities/k8s): gateway support 2025-05-12 15:19:42 +04:00
ee598560ec Merge pull request #3572 from Infisical/daniel/fix-secret-scaninng-public-keys
fix: update secret scanner to latest version
2025-05-12 11:13:51 +04:00
2793ac22aa remove duplicate field 2025-05-11 22:27:09 -04:00
31fad03af8 Return metadata with identity post endpoints 2025-05-09 23:41:11 -04:00
ce612877b8 docs 2025-05-09 22:47:20 -04:00
4ad8b468d5 Merge branch 'main' into ENG-2706 2025-05-09 22:37:22 -04:00
5742fc648b add tenancy OCID requirement 2025-05-09 22:33:02 -04:00
c629705c9c Merge pull request #3535 from Infisical/feat/addGroupsToSshHosts
feat(ssh-hosts): Add groups to ssh hosts allowed principals
2025-05-09 22:52:35 -03:00
aa68a3ef58 feature: add org role duplication 2025-05-09 14:29:18 -07:00
be10f6e52a Merge pull request #3579 from Infisical/daniel/horizontal-scaling-ms-teams
fix(workflow-integrations): microsoft teams scaling issues
2025-05-10 01:11:37 +04:00
40c5ff0ad6 Merge pull request #3578 from Infisical/project-template-improvements
improvement(project-templates): Project templates UI improvements
2025-05-09 13:50:50 -07:00
8ecb5ca7bc remove extra margin 2025-05-09 13:47:28 -07:00
ab6a2b7dbb fix(workflow-integrations): microsoft teams scaling issues 2025-05-10 00:47:22 +04:00
81bfc04e7c Trim hostname input on SSH Host permission form and fix getWorkspaceUsers key invalidation 2025-05-09 17:10:01 -03:00
a757fceaed Merge pull request #3577 from Infisical/feat/docs-support-openapi-titles
feat(docs): Support OpenAPI titles for Zod descriptions
2025-05-09 15:49:49 -04:00
ce8e18f620 improvement: address feedback 2025-05-09 12:40:07 -07:00
d09c964647 fix: use tanstack router link 2025-05-09 12:32:37 -07:00
eeddbde600 improvement: update org project templates relocation banner 2025-05-09 12:23:05 -07:00
9e1d38a27b Add PIT rollback 2025-05-09 16:03:50 -03:00
859b643e43 Delete ssh 2025-05-09 22:49:39 +04:00
91f71e0ef6 feat(cli): upgrade secret scanner 2025-05-09 22:48:56 +04:00
4e9e31eeb7 added credit 2025-05-09 13:45:36 -04:00
f6bc99b964 support openapi titles for zod description 2025-05-09 13:40:15 -04:00
679eb9dffc fix: correct project templates empty table display if feature is disabled 2025-05-09 10:14:03 -07:00
0754ae3aaf Merge pull request #3576 from Infisical/ENG-2692
feat(api): Rate limit for all email-sending endpoints
2025-05-09 11:37:08 -04:00
519a0c1bdf Merge branch 'main' into ENG-2692 2025-05-09 11:31:05 -04:00
e9d8979cf4 add rate limit to all email-sending endpoints 2025-05-09 11:29:53 -04:00
486d975fa0 Merge pull request #3575 from akhilmhdh/fix/octokit
feat: resolved esm error in octokit
2025-05-09 10:50:25 -04:00
=
42c49949b4 feat: resolved esm error in octokit 2025-05-09 20:13:08 +05:30
aea44088db Merge branch 'main' into feat/addGroupsToSshHosts 2025-05-09 09:21:29 -03:00
78d5bc823d PIT: Add folder reconstruction functions 2025-05-09 09:20:17 -03:00
578a0d7d93 review fixes 2025-05-09 02:54:49 -04:00
cd71db416d cancel deletion + update on creation for scheduled for deletion secrets 2025-05-09 02:34:50 -04:00
9d682ca874 added RE2 to regex 2025-05-09 02:10:53 -04:00
9054db80ad truncation and UI tweaks 2025-05-09 02:05:30 -04:00
5bb8756c67 only list compartments which the user is authorized to 'use vaults' in 2025-05-09 01:49:34 -04:00
8b7cb4c4eb Merge branch 'main' into ENG-2636 2025-05-09 01:34:19 -04:00
a6ee6fc4ea docs, grammar fixes, frontend tweak 2025-05-09 01:29:11 -04:00
e584c9ea95 test 2025-05-09 09:04:30 +04:00
428c60880a Update jumpcloud.mdx 2025-05-09 00:28:20 -04:00
2179b9a4d7 Update general.mdx 2025-05-09 00:27:43 -04:00
b21c17572d block local and private IPs on host header 2025-05-09 00:08:02 -04:00
44c7be54cf improvement: address feedback 2025-05-08 20:22:42 -07:00
45c08b3f09 improvement: improve role not found error display 2025-05-08 20:15:47 -07:00
57a29577fe feature: duplicate project role 2025-05-08 20:10:25 -07:00
2700a96df4 Remove unused package 2025-05-08 21:30:40 -04:00
7457ef3b66 bug fix 2025-05-08 21:24:03 -04:00
806df70dd7 tweaks 2025-05-08 21:03:58 -04:00
8eda358c17 schema gen 2025-05-08 20:59:05 -04:00
b34aabe72b merges 2025-05-08 20:56:04 -04:00
1921763fa8 fix: update to upcoming version 2025-05-09 04:43:13 +04:00
dfaed3c513 oci machine identity auth option 2025-05-08 20:42:58 -04:00
5408859a18 fix: update gitleaks/go-diff to latest version 2025-05-09 04:40:09 +04:00
8dfc0cfbe0 Merge pull request #3571 from Infisical/daniel/identities-ldap-docs
docs(identities): ldap auth
2025-05-09 04:15:11 +04:00
060199e58c fix: machine identities -> identities 2025-05-09 04:13:11 +04:00
3b9b17f8d5 requested changes 2025-05-09 04:12:21 +04:00
6addde2650 docs(identities): ldap auth 2025-05-09 03:44:15 +04:00
5b7627585f improvements: address feedback 2025-05-08 16:17:25 -07:00
800ea5ce78 feature: project role templates 2025-05-08 16:02:41 -07:00
a6b3be72a9 Make minor PR adjustments 2025-05-08 14:02:25 -07:00
394bd6755f Merge pull request #3566 from Infisical/daniel/identity-ldap-auth
feat(identities): ldap auth
2025-05-08 23:53:47 +04:00
c21873ac4b Update identity-ldap-auth-router.ts 2025-05-08 23:48:08 +04:00
64b8c1a2de added filter check 2025-05-08 23:44:30 +04:00
de443c5ea1 fix: requested changes 2025-05-08 23:20:18 +04:00
a3b7df4e6b fix: addressed requested changes 2025-05-08 23:13:46 +04:00
531607dcb7 Revise pr based on greptile review 2025-05-08 10:37:33 -07:00
182de009b2 Fix lint issues 2025-05-08 10:01:44 -07:00
f1651ce171 Rename migration file 2025-05-08 09:10:49 -07:00
e1f563dbd4 Fix merge conflicts 2025-05-08 09:07:28 -07:00
107cca0b62 Complete preliminary docs for pki subscribers 2025-05-08 08:52:10 -07:00
72abc08f04 Merge branch 'main' into ENG-2636 2025-05-08 10:29:52 -04:00
a4b648ad95 misc: addressed tooltip display issue 2025-05-08 21:24:26 +08:00
e8d424bbb0 PIT: Add initialization and checkpoint logic 2025-05-08 09:41:01 -03:00
04a8931cf6 Merge pull request #3568 from Infisical/pki-merge-fix
small migration fix
2025-05-08 01:23:36 -04:00
ab0b8c0f10 migration tweak 2025-05-08 01:22:34 -04:00
258836a605 migration tweak 2025-05-08 01:17:47 -04:00
d6b31cde44 greptile review fixes 2025-05-08 01:16:42 -04:00
2c94f9ec3c revert eslint memory increase 2025-05-08 00:50:31 -04:00
42ad63b58d increase max old space size for lint:fix 2025-05-08 00:44:03 -04:00
f2d5112585 Merge branch 'main' into ENG-2636 2025-05-08 00:27:28 -04:00
9c7b25de49 docs + tweaks 2025-05-08 00:25:19 -04:00
0b31d7f860 feat(identities): ldap auth, requested changes 2025-05-08 08:14:29 +04:00
5c91d380b8 feat(identities): ldap auth 2025-05-08 07:55:22 +04:00
b908893a68 feat(identities): ldap auth 2025-05-08 07:49:23 +04:00
4d0275e589 Merge pull request #3565 from Infisical/remove-migration-folder
Remove unused migration folder
2025-05-07 20:53:51 -04:00
6ca7a990f3 unused folder remove 2025-05-07 20:34:01 -04:00
befd77eec2 Merge pull request #3563 from Infisical/policy-selection-modal
improvement(project-roles): Add Policy Selection Modal
2025-05-07 16:49:05 -07:00
1d44774913 Merge pull request #3564 from Infisical/daniel/generator-doc-imp
docs(k8s/generators): improve documentation
2025-05-08 03:20:30 +04:00
984552eea9 rephrase generator overview 2025-05-07 19:18:45 -04:00
b6a957a30d fix: select all apply to filtered policies only, skip replacing existing policies 2025-05-07 15:34:34 -07:00
36954a9df9 secret sync + tweaks 2025-05-07 17:57:00 -04:00
2f4efad8ae Update infisical-push-secret-crd.mdx 2025-05-08 01:47:00 +04:00
16c476d78c fix: correct policies typos 2025-05-07 14:09:32 -07:00
68c549f1c6 improvement: add select polices modal 2025-05-07 13:50:27 -07:00
0610416677 Merge pull request #3550 from Infisical/project-specific-default-roles
Improvements: Refactor Project Templates and Project Type Policy Filtering/Specific Roles
2025-05-07 12:50:01 -07:00
4a37dc9cb7 Merge pull request #3561 from Infisical/helm-update-v0.9.2
Update Helm chart to version v0.9.2
2025-05-07 22:37:58 +04:00
7e432a4297 Update Helm chart to version v0.9.2 2025-05-07 18:27:13 +00:00
794fc9c2a2 improvements: address feedback 2025-05-07 11:23:51 -07:00
d4e5d2c7ed Merge pull request #3540 from Infisical/daniel/generators
feat(k8s): generator support
2025-05-07 22:10:22 +04:00
581840a701 fixed app connection endpoints 2025-05-07 13:53:05 -04:00
0c2e0bb0f9 Merge pull request #3560 from Infisical/misc/add-default-old-space-config
misc: add default old space config
2025-05-08 01:46:46 +08:00
e2a414ffff misc: add default old space config 2025-05-08 01:39:56 +08:00
=
0ca3c2bb68 feat: added password generator crd to samples 2025-05-07 22:50:49 +05:30
083581b51a Merge pull request #3554 from Infisical/feat/new-project-properties-for-tf-management
feat: adjustments to properties and validation
2025-05-07 20:22:23 +04:00
40e976133c Merge pull request #3528 from Infisical/ENG-2647
feat(admin): Invalidate Cache
2025-05-07 11:50:57 -04:00
ad2f002822 Merge pull request #3558 from Infisical/pki-docs-patch
docs fix
2025-05-07 11:06:24 -04:00
8842dfe5d1 docs fix 2025-05-07 11:01:19 -04:00
326742c2d5 feat(app-connections): OCI 2025-05-07 10:59:27 -04:00
f0c52cc8da Add comments to provide context on this change 2025-05-07 08:43:56 -03:00
e58dbe853e Minor improvements on commits code quality 2025-05-07 08:38:19 -03:00
b1eea4ae9c Merge pull request #3556 from Infisical/misc/remove-unnecessary-key-encryption-for-service-token
misc: removed unnecessary key encryption for service token
2025-05-07 16:41:51 +08:00
a8e0a8aca3 misc: removed unnecessary key encryption for service token 2025-05-07 16:36:10 +08:00
=
b37058d0e2 feat: switched to is fetching 2025-05-07 11:30:31 +05:30
c891b8f5d3 fix routing 2025-05-07 03:00:20 +04:00
a32bb95703 Start work on PkiSubscriberDetailsByIDPage 2025-05-06 15:46:54 -07:00
334a05d5f1 fix lint 2025-05-06 18:08:08 -04:00
12c813928c fix polling 2025-05-06 18:00:24 -04:00
f493a617b1 Add new commit logic on every folder/secret operation 2025-05-06 18:57:25 -03:00
521fef6fca Merge branch 'main' into ENG-2647 2025-05-06 17:00:40 -04:00
=
8f8236c445 feat: simplied the caching panel logic and fixed permission issue 2025-05-07 01:37:26 +05:30
3cf5c534ff Merge pull request #3553 from Infisical/pki-docs-patch
patch(docs): mint.json update
2025-05-06 15:54:31 -04:00
2b03c295f9 feat: adjustments to properties and validation 2025-05-07 03:51:22 +08:00
4fc7a52941 patch(docs): mint.json update 2025-05-06 15:38:10 -04:00
0ded2e51ba fix: filter project templates polices by type 2025-05-06 11:59:59 -07:00
0d2b3adec7 Merge pull request #3551 from Infisical/maidul98-patch-11
Add Conduct and Enforcement to bug bounty
2025-05-06 14:50:17 -04:00
e695203c05 Update docs/internals/bug-bounty.mdx
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-06 14:49:38 -04:00
f9d76aae5d Update bug-bounty.mdx 2025-05-06 14:46:42 -04:00
1c280759d1 Merge pull request #3548 from Infisical/daniel/self-hosted-secret-scanning
docs: secret scanning self hosted documentation
2025-05-06 22:27:00 +04:00
4562f57b54 improvements: refactor project templates, filter policies by project type, project type specific roles 2025-05-06 11:26:09 -07:00
6005dce44d fix: allow secret scanning from all self-hosted orgs 2025-05-06 22:16:29 +04:00
0410c83cef Fix merge conflicts 2025-05-06 09:46:31 -07:00
cf4f2ea6b1 Begin developing pki subscriber 2025-05-06 09:44:57 -07:00
bf85df7e36 Fix SSH table UI user groups issues 2025-05-06 08:37:19 -03:00
32a3e1d200 commit 2025-05-06 08:11:50 -03:00
f7f7d2d528 fix: typo 2025-05-06 08:24:59 +04:00
57342cf2a0 docs: secret scanning self hosted documentation 2025-05-06 08:14:05 +04:00
d530604b51 Merge pull request #3547 from Infisical/add-host-to-envar
Add missing HOST environment var
2025-05-05 20:46:20 -04:00
229c7c0dcf Add missing HOST environment var
Added missing HOST environment var
2025-05-05 20:43:45 -04:00
6a79830e01 Update bug-bounty.mdx 2025-05-05 17:32:18 -04:00
7447d17e94 bug fix, migration fix, frontend tweak 2025-05-05 17:21:59 -04:00
4efa4ad8df merging PKI PRs 2025-05-05 17:06:32 -04:00
722067f86c Merge pull request #3514 from Infisical/ENG-2685
feat(pki): Store Secret Key Alongside Certificate + Endpoints to Fetch PK / Cert Bundle
2025-05-05 16:12:48 -04:00
86bb2659b5 small ui tweaks 2025-05-05 16:07:04 -04:00
dc59f226b6 swapped polling to react query 2025-05-05 15:58:45 -04:00
c6e56f0380 Stop removing secret/folder versions on projects with version >= 3 2025-05-05 16:43:58 -03:00
cd9792822b Merge pull request #3545 from Infisical/fix-dns-resolve-fallback
fix(external-connections): Use DNS Lookup as Fallback for DNS Resolve
2025-05-05 12:37:26 -07:00
9175c1dffa Merge branch 'main' into ENG-2647 2025-05-05 15:27:25 -04:00
210f1dc2a2 fix: revert dev comment out 2025-05-05 12:24:12 -07:00
7851bb8710 improvement: address feedback 2025-05-05 12:23:18 -07:00
f6e802c017 review fixes: docs + frontend 2025-05-05 15:07:57 -04:00
d28c87ee67 fix: use dns lookup as fallback for dns resolve 2025-05-05 11:56:49 -07:00
b6e6a3c6be docs changes 2025-05-05 14:50:54 -04:00
54927454bf ui fetch private key if permission allows it 2025-05-05 14:37:20 -04:00
b9070a8fa3 Merge branch 'main' into feat/addGroupsToSshHosts 2025-05-05 14:51:01 -03:00
1ce06891a5 ui tweak for role policies 2025-05-05 13:43:38 -04:00
3a8154eddc Merge branch 'main' into ENG-2685 2025-05-05 13:37:43 -04:00
d61216ed62 Merge branch 'main' into ENG-2661 2025-05-05 13:33:19 -04:00
95b6676976 Merge pull request #3539 from Infisical/daniel/gateway-helm-docs
docs(gateway-helm): helm deployment
2025-05-05 17:45:36 +04:00
15c0834d56 Merge pull request #3530 from Infisical/email-revamp
improvemet(email-templates): migrate email templates to react email
2025-05-04 23:04:38 -04:00
1e4dfd0c7c fix(k8s/generators): update base crds 2025-05-05 02:35:57 +04:00
34b7d28e2f requested changes 2025-05-05 02:30:59 +04:00
245a348517 Update generators.go 2025-05-05 02:13:12 +04:00
e0fc582e2e docs(k8s/generators): docs and minor fix 2025-05-05 02:09:21 +04:00
68ef897b6a fix: logs and rbac 2025-05-05 01:39:30 +04:00
1b060e76de Update kustomization.yaml 2025-05-05 01:08:22 +04:00
9f7599b2a1 feat(k8s): generators 2025-05-05 00:59:11 +04:00
edd415aed8 Update overview.mdx 2025-05-05 00:40:49 +04:00
c816cbc9a9 docs(gateway-helm): helm deployment 2025-05-05 00:09:59 +04:00
416811d594 Merge pull request #3524 from Infisical/daniel/gateway-helm
feat(helm): infisical helm
2025-05-04 23:52:19 +04:00
80a9d2bba9 Merge pull request #3538 from Infisical/doc/add-auto-deployment-ref-for-daemonsets-and-statefulsets
doc: added daemonset and statefulset auto-redeploy example
2025-05-04 14:16:41 -04:00
f5e34ea59e doc: added daemonset and statefulset auto-redeploy example 2025-05-04 15:28:12 +00:00
x
9cbe70a6f3 lint fixes 2025-05-02 20:10:30 -04:00
x
f49fb534ab review fixes 2025-05-02 19:50:55 -04:00
x
6eea4c8364 frontend tweaks 2025-05-02 19:20:02 -04:00
x
1e206ee441 Merge branch 'main' into ENG-2647 2025-05-02 19:03:08 -04:00
bec3cec040 fix: correct secret-scanning link 2025-05-02 15:52:13 -07:00
x
85c1a1081e checkpoint 2025-05-02 18:43:07 -04:00
d1122886fd Merge pull request #3532 from Infisical/add-missing-identity-specific-privilege-v2-docs-api
Add identity-specific-privilege v2 API to docs
2025-05-02 16:46:45 -04:00
3757f190f0 Merge pull request #3522 from Infisical/host-groups
Infisical SSH - Add Support for Host Groups
2025-05-02 13:46:02 -07:00
fec55bc9f8 fix greptile recs 2025-05-02 16:40:56 -04:00
a285a14fff Fix SshHostsTable component 2025-05-02 13:38:21 -07:00
9ec7d0d03e Update login mapping rendering on ssh hosts 2025-05-02 13:37:39 -07:00
d5246c2891 Update rendering on login mappings on hosts table 2025-05-02 13:30:48 -07:00
dcb7215b7d requested changes 2025-05-03 00:20:25 +04:00
c0f383ce1d Merge pull request #3536 from Infisical/vite-allowed-hosts
feat(vite.config): Allowed Hosts Defined Through Env Variable
2025-05-02 16:16:40 -04:00
0dcb223f80 Fix merge conflicts 2025-05-02 13:06:18 -07:00
x
877485b45a queue job 2025-05-02 15:23:35 -04:00
f9f098af86 fix: try updating tsup.config to account for .tsx 2025-05-02 12:20:17 -07:00
6a5748150a Revise PR based on review 2025-05-02 12:16:51 -07:00
3ef053f255 fix: test adding explicity .tsx path 2025-05-02 12:13:23 -07:00
ed914d49ee Merge pull request #3531 from Infisical/feat/githubSsoDefaultOrganizationSetting
Add Github SSO users to default organization on signup
2025-05-02 15:59:33 -03:00
8f7a652741 fix: correct imports 2025-05-02 11:57:18 -07:00
x
e43f583eb6 feat(vite.config): Allowed Hosts Defined Through Env Variable 2025-05-02 14:45:44 -04:00
717c947e53 fix: try removing jsx usage 2025-05-02 11:42:20 -07:00
8ad334b3ab fix: try reverting ts jsx type 2025-05-02 11:34:18 -07:00
c7e707f20a improvement: address feedback 2025-05-02 11:08:41 -07:00
x
d13e685a81 emphasize that secrets cache is encrypted in frontend 2025-05-02 13:04:22 -04:00
x
9849a5f136 switched to applyJitter functions 2025-05-02 13:00:37 -04:00
x
26773a1444 merge 2025-05-02 12:57:28 -04:00
3ea450e94a Add groups to ssh hosts allowed principals fix delete principal row issue 2025-05-02 13:41:53 -03:00
7d0574087c Add groups to ssh hosts allowed principals bot improvements 2025-05-02 13:36:05 -03:00
46755f724c Improve /complete-account/signup body schema 2025-05-02 13:06:45 -03:00
e12f4ad253 Add cloud check on github add user to default org 2025-05-02 12:58:36 -03:00
36916704be Add groups to ssh hosts allowed principals 2025-05-02 11:14:43 -03:00
5dbded60f4 Delete Dockerfile.gateway 2025-05-02 16:38:31 +04:00
a80d5f10e5 fix(gateway-helm): requested changes 2025-05-02 16:38:02 +04:00
0faa8f4bb0 Merge pull request #3533 from Infisical/doc/add-mention-of-pkce-and-eddsa-alg
doc: add mentions of PKCE and eddsa alg for oidc
2025-05-02 19:42:33 +08:00
365b4b975e Add minor improvements to Github SSO users added to default organization on signup 2025-05-02 08:22:47 -03:00
fbf634f7da doc: add mentions of PKCE and eddsa alg for oidc 2025-05-02 07:57:37 +00:00
47bb3c10fa Add identity-specific-privilege v2 API to docs
Add identity-specific-privilege v2 API to docs
2025-05-02 00:32:17 -04:00
1f3e7da3b7 Merge pull request #3487 from Infisical/ENG-2633
feat(secret-sync): Hashicorp Vault App Connection & Secret Sync
2025-05-01 20:31:18 -04:00
81396f6b51 Small docs change 2025-05-01 20:23:29 -04:00
63279280fd Add Github SSO users to default organization on signup 2025-05-01 20:41:30 -03:00
66fbcc6806 improvemet(email-templates): migrate email templates to react email 2025-05-01 14:57:24 -07:00
x
a6f280197b spelling fix 2025-05-01 17:37:54 -04:00
x
346d2f213e improvements + review fixes 2025-05-01 17:33:24 -04:00
f2d9593660 Merge pull request #3486 from Infisical/daniel/ms-teams-integration
feat(workflow-integrations): microsoft teams
2025-05-02 00:46:19 +04:00
219964a242 fix: query invalidation 2025-05-02 00:41:46 +04:00
x
9f1ac77afa invalidate cache 2025-05-01 16:34:29 -04:00
240f558231 fix: added empty state 2025-05-01 23:49:18 +04:00
f3b3df1010 Update MicrosoftTeamsIntegrationForm.tsx 2025-05-01 20:43:23 +04:00
1fd6cd4787 Update MicrosoftTeamsIntegrationForm.tsx 2025-05-01 20:34:09 +04:00
a7d715ed08 Update MicrosoftTeamsIntegrationForm.tsx 2025-05-01 20:26:47 +04:00
x
a758503f40 new paths get created 2025-05-01 11:53:41 -04:00
550cb2b5ec smaller ui improvements 2025-05-01 19:50:50 +04:00
75cb259c51 add description tooltip 2025-05-01 19:15:29 +04:00
x
be2c5a9e57 merge conflicts 2025-05-01 10:48:33 -04:00
a077a9d6f2 Update OauthCallbackPage.tsx 2025-05-01 18:27:29 +04:00
296493484f Merge pull request #3525 from Infisical/ENG-2669
feat(agent): Sync Imported Secrets
2025-05-01 10:14:41 -04:00
835b2fba9c requested changes 2025-05-01 18:02:27 +04:00
92bc9d48af Merge pull request #3527 from Infisical/misc/addressed-totp-visibility-issue
misc: addressed totp and sms visibility issue
2025-05-01 21:06:32 +08:00
a9c1c197f7 misc: added min width 2025-05-01 20:35:29 +08:00
5bd7dd4d65 Merge pull request #3521 from Infisical/bug-bounty-program
Add bug bounty program
2025-05-01 08:35:11 -04:00
8e2cfe2c03 misc: addressed totp visibility issue 2025-05-01 20:26:49 +08:00
x
0bb107d61d feat(agent): Sync Imported Secrets 2025-04-30 22:58:07 -04:00
82c7dad6c8 feat(helm): infisical helm 2025-05-01 06:45:40 +04:00
83df0850ce Fix frontend lint issues 2025-04-30 19:44:56 -07:00
ae43435509 Revise PR based on coderabbit, greptile review 2025-04-30 19:39:02 -07:00
x
580de0565b review fixes 2025-04-30 22:24:26 -04:00
x
bbfd4a44c3 small comment changes 2025-04-30 21:41:28 -04:00
x
01e13ca7bd small tweaks 2025-04-30 21:36:11 -04:00
7811178261 Fix merge conflicts 2025-04-30 18:32:56 -07:00
x
f5fdd1a266 Merge branch 'main' into ENG-2661 2025-04-30 21:20:17 -04:00
b21b0b340b Complete preliminary ssh host group feature 2025-04-30 18:14:31 -07:00
fdbb930940 Merge pull request #3520 from Infisical/daniel/fix-project-deletion
fix(api): project deletion failing
2025-04-30 20:21:02 -04:00
x
bda74ce13e logging, finalizing some functions, and other tweaks 2025-04-30 20:20:31 -04:00
9e56790886 Update OauthCallbackPage.tsx 2025-05-01 04:13:46 +04:00
e08c5f265e fix: improve auth step to avoid takeovers 2025-05-01 04:08:58 +04:00
e7a55d8a27 Merge pull request #3440 from Infisical/feat/azureClientSecretsRotation
Feat/azure client secrets rotation
2025-04-30 19:45:02 -04:00
35b8adb0f6 Fix order of Secret Rotation docs 2025-04-30 20:13:20 -03:00
d161be1170 Improve error propagation and change appId to objectId to match azure 2025-04-30 20:06:13 -03:00
aabf933756 Add bug bounty program
Added a formal bounty program
2025-04-30 18:56:23 -04:00
5d44d58ff4 update postgres reqs 2025-04-30 17:53:41 -04:00
x
1268bc1238 coderabbit review fixes 2025-04-30 17:50:23 -04:00
x
07e4bc8eed review fixes 2025-04-30 17:46:05 -04:00
69ef7fdf3b Update index.ts 2025-05-01 01:32:45 +04:00
ff294dab8d Merge pull request #3507 from Infisical/feat/orgUserAuthTokenExpiration
feat(user-auth): make users auth token expiration customizable for orgs
2025-04-30 18:18:38 -03:00
a01a9f3f77 Fix bug on azure revokeCredentials and limit expiration to 5 years 2025-04-30 18:16:48 -03:00
x
6a973be6f3 cert chain tweaks 2025-04-30 16:26:31 -04:00
c99440ba81 feat(user-auth): use ms library and update docs 2025-04-30 16:49:33 -03:00
6d5a6f42e0 Merge branch 'main' into feat/orgUserAuthTokenExpiration 2025-04-30 15:59:52 -03:00
x
235be96ded tweaks 2025-04-30 14:53:57 -04:00
d0a642a63a Change Azure Client Secret Rotation to show app client id 2025-04-30 15:17:24 -03:00
x
30471bfcad Merge branch 'main' into ENG-2685 2025-04-30 13:41:14 -04:00
x
7f836ed9bc update a few endpoints to not rely on CA 2025-04-30 13:39:50 -04:00
cf84dde0fa Address PR comments for Azure Client Secret Rotation 2025-04-30 13:56:01 -03:00
x
4d847ab2cb ca relation removal migration 2025-04-30 12:16:40 -04:00
0c027fdc43 Merge pull request #3516 from Infisical/feat/teamcity-root-project
remove _Root filter for projects
2025-04-30 12:07:24 -04:00
x
80cecbb937 Merge branch 'main' into ENG-2661 2025-04-30 10:49:36 -04:00
x
727a6a7701 remove _Root filter for projects 2025-04-30 10:31:40 -04:00
98bb5d7aa7 Address PR comments for Azure Client Secret Rotation 2025-04-30 10:11:38 -03:00
7f1f9e7fd0 Merge pull request #3491 from Infisical/feat/improveSecretReferenceWarning
feat(secrets-ui): Add direct reference warning on secrets updates and add secret sync warning on deletion
2025-04-30 08:17:55 -03:00
b06eeb0d40 Add add/remove/list hosts in ssh host groups functionality 2025-04-29 23:31:57 -07:00
x
eedffffc38 review fixes 2025-04-30 02:07:07 -04:00
x
5d366687a5 review fixes 2025-04-30 01:16:40 -04:00
x
4720914839 Merge branch 'main' into ENG-2633 2025-04-30 00:54:37 -04:00
x
9f487ad026 frontend type fixes 2025-04-30 00:53:31 -04:00
x
c70b9e665e more tweaks and type fix 2025-04-30 00:39:10 -04:00
x
d460e96052 Merge branch 'main' into ENG-2685 2025-04-30 00:34:37 -04:00
x
e475774910 made certificates store PK and chain in relation to the main table, added /bundle endpoints, new audit log and permission entries 2025-04-30 00:33:46 -04:00
98f742a807 Merge pull request #3513 from Infisical/daniel/k8s-hsm-docs
docs: fix hsm kubernetes documentation
2025-04-30 06:10:30 +04:00
66f1967f88 Update hsm-integration.mdx 2025-04-30 05:37:55 +04:00
da6cf85c8d fix: remove log output file 2025-04-30 05:37:07 +04:00
e8b6eb0573 docs: fix hsm kubernetes documentation 2025-04-30 05:09:39 +04:00
03ad5c5db0 Merge pull request #3512 from Infisical/daniel/kms-docs
docs: prerequisite for aws key
2025-04-29 20:39:30 -04:00
x
e81c49500b get certificate private key endpoint + migrations 2025-04-29 20:34:39 -04:00
e6c4c27a87 docs: added pre-req for aws key 2025-04-30 03:36:07 +04:00
x
8b6c97d5bc checkpoint frontend 2025-04-29 19:26:07 -04:00
x
5641d334cd checkpoint 2025-04-29 19:24:00 -04:00
2a28d74bde Address PR comments for Azure Client Secret Rotation 2025-04-29 20:19:30 -03:00
d4ac4f8d8f Update CollapsibleSecretImports.tsx 2025-04-30 03:13:10 +04:00
aedc6e16ad Update .infisicalignore 2025-04-30 02:51:48 +04:00
1ec7c67212 Merge branch 'heads/main' into daniel/ms-teams-integration 2025-04-30 02:39:08 +04:00
ff0ff622a6 requested changes 2025-04-30 02:35:07 +04:00
511becabd8 Merge branch 'main' into feat/azureClientSecretsRotation 2025-04-29 19:26:14 -03:00
f0229c5ecf feat(user-auth): fix migration bug for e2e suite 2025-04-29 18:48:08 -03:00
8d711af23b feat(secrets-ui): change secret sync icon color 2025-04-29 18:39:41 -03:00
7bd61d88fc feat(user-auth): improve token refresh logic and default values 2025-04-29 18:28:18 -03:00
a9a16c9bd1 Begin work on ssh host groups 2025-04-29 13:39:24 -07:00
929434d17f docs: improved ms teams workflow integration self-hosting docs 2025-04-30 00:15:58 +04:00
ba94b91974 Merge pull request #3510 from Infisical/internal-ip-check-fix
fix(external-connections): Use Hostname for Blocking Internal IPs DNS Resolve
2025-04-29 12:37:46 -07:00
b65f62fda8 fix: use hostname for blocking internal IPs 2025-04-29 12:26:29 -07:00
c47d76a6c7 feat(secrets-ui): improve warning message table 2025-04-29 14:19:52 -03:00
9138a9e71d Merge pull request #3509 from Infisical/feat/teamcity-ignore-inherited-secrets
feat(secret-sync): TeamCity ignore inherited and non-env values
2025-04-29 12:49:01 -04:00
x
8e4ad8baf8 docs tweak 2025-04-29 12:43:44 -04:00
x
9f158d5b3f feat(docs): Added note stating that inherited secrets are ignored 2025-04-29 10:35:56 -04:00
x
0e1cb4ebb2 Merge branch 'main' into feat/teamcity-ignore-inherited-secrets 2025-04-29 10:31:51 -04:00
e959ed7fab feat(secrets-ui): improve warning message and logic for secret-sync on secret imports 2025-04-29 10:15:53 -03:00
4e4b1b689b Merge branch 'main' into feat/improveSecretReferenceWarning 2025-04-29 08:43:35 -03:00
8f07f43fbd Merge pull request #3504 from akhilmhdh/doc/assume-privilege
doc: added doc for assume privilege feature
2025-04-28 20:08:44 -07:00
023f5d1286 revise docs 2025-04-28 23:06:37 -04:00
72b03d4bdf Merge pull request #3506 from Infisical/daniel/build-strict-find-filter
feat: strict find filter
2025-04-29 05:41:39 +04:00
e870e35002 consolidated filtering functions into one 2025-04-29 04:27:10 +04:00
4544f621af Merge pull request #3478 from Infisical/fix/UISecretEditPermissionButNotReadValuePermission
fix(secrets-table): UI fix for users with edit permissions but not read secret value permission
2025-04-28 20:23:34 -03:00
x
ddb5098eda only sync non-inherited environment variables 2025-04-28 19:09:13 -04:00
35749e8d12 feat(user-auth): allow edit overwritter rotation value on overview table 2025-04-28 20:02:50 -03:00
x
ee2e2246da solved merge conflicts 2025-04-28 18:51:20 -04:00
x
e30d400afa Support for namespaces (for HCP) 2025-04-28 18:34:33 -04:00
024ed0c0d8 feat(user-auth): add pr suggestions 2025-04-28 18:19:44 -03:00
e99e360339 feat(user-auth): make users auth token expiration customizable for orgs 2025-04-28 17:43:10 -03:00
85965184f8 Update secret-v2-bridge-dal.ts 2025-04-29 00:18:13 +04:00
a1bbd50c0b feat: build strict find filter 2025-04-29 00:09:30 +04:00
f9c936865a feat(secrets-ui): minor improvements from PR suggestions 2025-04-28 16:49:29 -03:00
2be10b5f9d Merge pull request #3503 from Infisical/feat/add-support-for-eddsa-jwt-alg
feat: add support for eddsa jwt alg for oidc
2025-04-29 03:27:58 +08:00
3b6e35e13c Merge pull request #3505 from akhilmhdh/feat/cache-jitter
feat: increased secret caching to 10mins with jitter of 2min
2025-04-28 12:16:00 -07:00
=
fcf984965e feat: increased secret caching to 10mins with jitter of 2min 2025-04-29 00:36:39 +05:30
=
6bca854475 doc: added doc for assume privilege feature 2025-04-29 00:12:37 +05:30
a69ce50da9 Merge pull request #3495 from Infisical/ENG-2656
feat(login): Update all SSO login methods to use PKCE
2025-04-28 14:33:02 -04:00
1b798bd5d5 misc: fixed casing 2025-04-29 02:08:13 +08:00
bd3ebe75c9 feat: add support for eddsa jwt alg for oidc 2025-04-29 02:05:19 +08:00
0f2b8e4266 Update github-org-sync.mdx 2025-04-28 14:04:02 -04:00
x
c4ae8f2987 Remove false comment 2025-04-28 13:30:06 -04:00
x
b50a022d11 PKCE check logic fix 2025-04-28 13:28:47 -04:00
x
8a035c8d82 check if OIDC provider supports PKCE before applying it 2025-04-28 12:51:18 -04:00
4fa7ba2ec7 Merge branch 'main' into fix/UISecretEditPermissionButNotReadValuePermission 2025-04-28 13:33:05 -03:00
x
03d7f9f786 scope fix for google strategy 2025-04-28 12:17:04 -04:00
x
1b3e8b0a1c fixed merge conflicts 2025-04-28 10:52:12 -04:00
6a26a11cbb Merge pull request #3471 from Infisical/feat/add-support-for-org-sso-bypass-for-sso
feat: enabled sso (google, gitlab, github) to bypass org sso
2025-04-28 22:35:53 +08:00
d673c8d8e9 Merge pull request #3498 from akhilmhdh/feat/gh-sync
feat: github org sync
2025-04-28 07:26:07 -07:00
=
b39c7070b5 feat: linted merge issues 2025-04-28 19:51:10 +05:30
=
fa3dd03074 feat: updated review comments by @sheen 2025-04-28 19:48:57 +05:30
=
ee40ffd304 feat: changed get user to get org membership details 2025-04-28 19:48:56 +05:30
=
d3d76467ac feat: addressed rabbit and reptile feedback 2025-04-28 19:48:56 +05:30
=
58940f31e3 docs: added doc for github org sync 2025-04-28 19:48:56 +05:30
=
6d2175cf9f feat: completed github org sync 2025-04-28 19:48:56 +05:30
dbb0b28453 Merge pull request #3494 from Infisical/fix/moveablePermissionList
feat(project-permissions): allow users to sort permissions on the UI
2025-04-28 07:14:57 -07:00
225862aed8 Merge pull request #3453 from Infisical/daniel/reminders
feat(reminders): specify recipients
2025-04-28 18:14:23 +04:00
8d1bd6aabb Merge pull request #3447 from akhilmhdh/feat/assume-role
Implemented project permission impersonation
2025-04-28 06:59:09 -07:00
740c650441 fix import 2025-04-28 09:54:02 -04:00
78ccb5acb7 Merge pull request #3497 from Infisical/ssh-host-alias
Infisical SSH: Add Alias Field to SSH Hosts
2025-04-28 06:41:29 -07:00
e9aa8b317b Merge branch 'main' into feat/assume-role 2025-04-28 06:33:26 -07:00
=
7b42f666f9 feat: updated files on review changes 2025-04-28 18:56:17 +05:30
8a0cfa34d2 Merge pull request #3501 from Infisical/fix-kms-memory-leak
Fix KMS memory leak
2025-04-28 05:02:26 -07:00
ca9825c1fe remove unused logger 2025-04-28 07:59:00 -04:00
1dfc9511c1 throw only error and remove bool return 2025-04-28 07:55:33 -04:00
694ab35f53 Fix KMS memory leak
Adds a clean up method because KMS clients like GCP use a persistent connection snd if not closed, will continue to eat up the memory.
2025-04-28 07:48:31 -04:00
f35cd2d6a6 Update project-service.ts 2025-04-28 05:20:56 +04:00
b259428075 fix: secret scanning & route mismatch 2025-04-28 05:16:33 +04:00
f54a10f626 Merge branch 'heads/main' into daniel/ms-teams-integration 2025-04-28 05:08:04 +04:00
63a3ce2dba feat(workflow-integrations): ms-teams audit logs and pagination support 2025-04-28 04:58:25 +04:00
9aabc3ced7 better error logs 2025-04-28 04:07:32 +04:00
fe9ec6b030 docs(workflow-integrations): microsoft teams 2025-04-28 04:07:01 +04:00
44ae0519d1 Revise ssh host alias field handling/validation 2025-04-27 14:34:26 -07:00
3d89a7f45d Revise ssh host alias PR 2025-04-26 18:18:22 -07:00
de63c8cb6c Add alias field to ssh hosts for improved ux 2025-04-26 18:04:21 -07:00
632572f7c3 Merge pull request #3452 from Infisical/ldaps-connection-and-password-rotation
Feature: LDAP Connection and Password Rotation
2025-04-26 09:13:08 -07:00
bef55043f7 Update OrgWorkflowIntegrationTab.tsx 2025-04-26 10:16:30 +04:00
0323d152da feat(microsoft-teams): better authentication flow and doc references 2025-04-26 09:46:23 +04:00
0a5f6274f5 Update CreateReminderForm.tsx 2025-04-26 05:56:11 +04:00
11ee13676d fix: deletion corner cases 2025-04-26 05:55:25 +04:00
e7783fe6cc requested changes & edge cases 2025-04-26 05:19:02 +04:00
a524690d01 deconflict merge 2025-04-25 17:20:30 -07:00
c229d6888c feat(secrets-ui): allow read access to personal overrides 2025-04-25 20:41:44 -03:00
x
b6566943c6 solve merge conflicts 2025-04-25 19:11:00 -04:00
2e459c161d feat(project-permissions): type fix 2025-04-25 19:51:08 -03:00
x
680f1a2230 Merge branch 'main' into ENG-2656 2025-04-25 18:46:05 -04:00
x
68e21ba8ce PKCE for Github, Gitlab, Google, and OIDC SSO 2025-04-25 18:45:23 -04:00
1e9722474f feat(project-permissions): allow users to sort permissions on the UI 2025-04-25 19:35:42 -03:00
f93edbb37f Merge pull request #3493 from Infisical/improve-aws-connection-error-propagation
improvement(app-connections): Improve AWS Connection Error Propagation
2025-04-25 15:25:55 -07:00
f345801bd6 feat(secrets-ui): improve types and code quality 2025-04-25 18:17:33 -03:00
f460acf9b4 fix(secrets-permissions): Fix case for rotated secrets 2025-04-25 17:56:56 -03:00
4160009913 feat(secrets-ui): add direct reference warning on secrets updates 2025-04-25 17:38:43 -03:00
d5065af7e9 feat(secrets-ui): add secret syncs to referenced secret warning 2025-04-25 15:26:34 -03:00
68e88ddef8 feat(azure-client-secrets-rotation): add show credentials modal 2025-04-25 13:16:13 -03:00
a2909b8030 Merge branch 'main' into feat/azureClientSecretsRotation 2025-04-25 12:42:48 -03:00
3de5fa066b fix(secrets-permissions): Fix setTimeout and eye icon size 2025-04-25 08:54:25 -03:00
8987938642 fix(microsoft-teams-integration): bug fixes 2025-04-25 11:03:31 +04:00
x
3f00359459 implemented blockLocalAndPrivateIpAddresses 2025-04-24 23:53:20 -04:00
x
a5b5b90ca1 nit: make docs a bit more future proof and descriptive 2025-04-24 23:48:09 -04:00
x
fd0a00023b nit: organize docs sidebar alphabetically 2025-04-24 23:40:47 -04:00
x
dd112b3850 review fixes 2025-04-24 22:39:20 -04:00
b329b5aa4b improvements: address feedback 2025-04-24 19:35:56 -07:00
x
c01c58fdcb small nit for consistency 2025-04-24 22:10:21 -04:00
x
4bba207552 fix UpdateHCVaultConnectionSchema only supporting AccessToken 2025-04-24 22:09:06 -04:00
8563eb850b fix: ts errors 2025-04-25 05:40:28 +04:00
x
4225bf6e0e Merge branch 'main' into ENG-2633 2025-04-24 21:23:38 -04:00
x
fab385fdd9 feat(docs): Hashicorp Vault App Connection & Secret Sync Docs 2025-04-24 21:22:44 -04:00
a204629bef Merge branch 'heads/main' into daniel/ms-teams-integration 2025-04-25 05:22:35 +04:00
50679ba29d fix: requested changes 2025-04-25 05:22:17 +04:00
f5fa57d6c5 fix: further cleanup 2025-04-25 04:53:00 +04:00
6088ae09ab fix: cleanup 2025-04-25 04:40:46 +04:00
0de15bf70c fix: remove logs 2025-04-25 04:37:22 +04:00
b5d229a7c5 feat(native-integrations): microsoft teams 2025-04-25 04:35:40 +04:00
x
92084ccd47 feat(secrey-sync): Hashicorp Vault Secret Sync (and minor app connection fixes) 2025-04-24 18:54:05 -04:00
e0dc2dd6d8 improvements: address feedback 2025-04-24 13:44:43 -07:00
x
418ac20f91 feat(app-connections): Hashicorp Vault App Connection 2025-04-24 15:41:21 -04:00
b377d2a6b1 fix(secrets-permissions): Fix setTimeout 2025-04-24 11:15:42 -03:00
350272aa57 fix(secrets-permissions): UI improvements 2025-04-24 08:10:10 -03:00
95489e1b0a fix(secrets-permissions): UI improvements 2025-04-23 22:24:41 -03:00
56b3e7a76d fix(secrets-permissions): UI fix for users with edit permissions but not read secret value permission 2025-04-23 21:09:19 -03:00
9ea6eca560 requested changes 2025-04-23 21:40:01 +04:00
33dea34061 chore: removed unused pick 2025-04-22 18:51:40 -07:00
da68073e86 chore: revert secret rotation flag 2025-04-22 18:06:44 -07:00
7bd312a287 improvements: update regex checks 2025-04-22 17:57:59 -07:00
d61e6752d6 Merge branch 'main' into ldaps-connection-and-password-rotation 2025-04-22 17:42:48 -07:00
636aee2ea9 improvements: address feedback 2025-04-22 17:36:18 -07:00
d5888f9de7 misc: only append isAdminLogin query param when relevant 2025-04-23 03:27:22 +08:00
1590b528bf misc: used url search params 2025-04-23 03:07:50 +08:00
e30a05e3e8 Remove unnecessary password type 2025-04-22 15:49:05 -03:00
ce7798c48b Fix redirect url for azure secrets 2025-04-22 15:44:21 -03:00
75f1ce7b86 feat: enabled sso to bypass org sso 2025-04-23 02:28:58 +08:00
6ce1c4e19e Merge branch 'main' into feat/azureClientSecretsRotation 2025-04-22 14:25:56 -03:00
f08de1599d PR fix suggestions 2025-04-22 14:25:52 -03:00
=
a80520e425 feat: removed all impersonate word in ui 2025-04-21 23:29:25 +05:30
=
4aa3552060 feat: fixed ts issues 2025-04-21 21:30:28 +05:30
=
40781949a6 feat: updated ui based on feedback 2025-04-21 20:02:23 +05:30
7d4f223174 lint fix 2025-04-21 10:36:27 -03:00
ef47d0056f Merge branch 'main' into feat/azureClientSecretsRotation 2025-04-21 10:27:56 -03:00
ccd7b0062e Fix MAX_GENERATED_CREDENTIALS_LENGTH for azure credentials 2025-04-21 10:14:55 -03:00
=
2ee423174a feat: updated code by rabbit, reptile and maidul changes 2025-04-21 18:43:21 +05:30
=
649f7b560f feat: added audit log for assume 2025-04-21 18:43:21 +05:30
=
7219ba3b46 feat: implemented user role impersonation 2025-04-21 18:43:21 +05:30
6e65656360 Update CreateReminderForm.tsx 2025-04-19 07:15:29 +04:00
e0491c2056 Update types.ts 2025-04-19 07:11:22 +04:00
b8db15563a Update 20250419004044_secret-reminder-recipients.ts 2025-04-19 07:07:45 +04:00
9982ade219 feat(reminders): specify recipients 2025-04-19 06:59:22 +04:00
9032bbe514 feature: ldap connection and password rotation 2025-04-18 17:55:03 -07:00
c403ffa9f6 Add Azure Client Secrets Rotation docs 2025-04-16 06:33:38 -03:00
1184ea1b11 Add Azure Client Secrets Rotation 2025-04-16 05:04:41 -03:00
7d97a76ecc Merge branch 'auth0-connection-and-secret-rotation' into feat/azureClientSecretsRotation 2025-04-15 23:58:27 -03:00
a889f92528 Add Azure Client Secrets App Connection 2025-04-15 23:39:06 -03:00
1518 changed files with 71302 additions and 16490 deletions

View File

@ -0,0 +1,27 @@
name: Release Gateway Helm Chart
on:
workflow_dispatch:
jobs:
release-helm:
name: Release Helm Chart
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Helm
uses: azure/setup-helm@v3
with:
version: v3.10.0
- name: Install python
uses: actions/setup-python@v4
- name: Install Cloudsmith CLI
run: pip install --upgrade cloudsmith-cli
- name: Build and push helm package to CloudSmith
run: cd helm-charts && sh upload-gateway-cloudsmith.sh
env:
CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }}

View File

@ -24,3 +24,19 @@ frontend/src/hooks/api/secretRotationsV2/types/index.ts:generic-api-key:65
frontend/src/pages/secret-manager/SecretDashboardPage/components/SecretRotationListView/SecretRotationItem.tsx:generic-api-key:26
docs/documentation/platform/kms/overview.mdx:generic-api-key:281
docs/documentation/platform/kms/overview.mdx:generic-api-key:344
frontend/src/pages/secret-manager/OverviewPage/components/SecretOverviewTableRow/SecretOverviewTableRow.tsx:generic-api-key:85
docs/cli/commands/user.mdx:generic-api-key:51
frontend/src/pages/secret-manager/OverviewPage/components/SecretOverviewTableRow/SecretOverviewTableRow.tsx:generic-api-key:76
docs/integrations/app-connections/hashicorp-vault.mdx:generic-api-key:188
cli/detect/config/gitleaks.toml:gcp-api-key:567
cli/detect/config/gitleaks.toml:gcp-api-key:569
cli/detect/config/gitleaks.toml:gcp-api-key:570
cli/detect/config/gitleaks.toml:gcp-api-key:572
cli/detect/config/gitleaks.toml:gcp-api-key:574
cli/detect/config/gitleaks.toml:gcp-api-key:575
cli/detect/config/gitleaks.toml:gcp-api-key:576
cli/detect/config/gitleaks.toml:gcp-api-key:577
cli/detect/config/gitleaks.toml:gcp-api-key:578
cli/detect/config/gitleaks.toml:gcp-api-key:579
cli/detect/config/gitleaks.toml:gcp-api-key:581
cli/detect/config/gitleaks.toml:gcp-api-key:582

View File

@ -133,8 +133,8 @@ RUN apt-get update && apt-get install -y \
RUN printf "[FreeTDS]\nDescription = FreeTDS Driver\nDriver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so\nSetup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so\nFileUsage = 1\n" > /etc/odbcinst.ini
# Install Infisical CLI
RUN curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | bash \
&& apt-get update && apt-get install -y infisical=0.31.1 \
RUN curl -1sLf 'https://artifacts-cli.infisical.com/setup.deb.sh' | bash \
&& apt-get update && apt-get install -y infisical=0.41.2 \
&& rm -rf /var/lib/apt/lists/*
RUN groupadd -r -g 1001 nodejs && useradd -r -u 1001 -g nodejs non-root-user
@ -171,6 +171,7 @@ ENV NODE_ENV production
ENV STANDALONE_BUILD true
ENV STANDALONE_MODE true
ENV ChrystokiConfigurationPath=/usr/safenet/lunaclient/
ENV NODE_OPTIONS="--max-old-space-size=1024"
WORKDIR /backend

View File

@ -127,8 +127,8 @@ RUN apt-get update && apt-get install -y \
&& rm -rf /var/lib/apt/lists/*
# Install Infisical CLI
RUN curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | bash \
&& apt-get update && apt-get install -y infisical=0.31.1 \
RUN curl -1sLf 'https://artifacts-cli.infisical.com/setup.deb.sh' | bash \
&& apt-get update && apt-get install -y infisical=0.41.2 \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /
@ -168,6 +168,7 @@ ENV HTTPS_ENABLED false
ENV NODE_ENV production
ENV STANDALONE_BUILD true
ENV STANDALONE_MODE true
ENV NODE_OPTIONS="--max-old-space-size=1024"
WORKDIR /backend

View File

@ -69,6 +69,15 @@ module.exports = {
["^\\."]
]
}
],
"import/extensions": [
"error",
"ignorePackages",
{
"": "never", // this is required to get the .tsx to work...
ts: "never",
tsx: "never"
}
]
}
};

View File

@ -54,8 +54,8 @@ COPY --from=build /app .
# Install Infisical CLI
RUN apt-get install -y curl bash && \
curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | bash && \
apt-get update && apt-get install -y infisical=0.8.1 git
curl -1sLf 'https://artifacts-cli.infisical.com/setup.deb.sh' | bash && \
apt-get update && apt-get install -y infisical=0.41.2 git
HEALTHCHECK --interval=10s --timeout=3s --start-period=10s \
CMD node healthcheck.js

View File

@ -55,9 +55,9 @@ RUN mkdir -p /etc/softhsm2/tokens && \
# ? App setup
# Install Infisical CLI
RUN curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | bash && \
RUN curl -1sLf 'https://artifacts-cli.infisical.com/setup.deb.sh' | bash && \
apt-get update && \
apt-get install -y infisical=0.8.1
apt-get install -y infisical=0.41.2
WORKDIR /app

View File

@ -64,9 +64,9 @@ RUN wget https://www.openssl.org/source/openssl-3.1.2.tar.gz \
# ? App setup
# Install Infisical CLI
RUN curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | bash && \
RUN curl -1sLf 'https://artifacts-cli.infisical.com/setup.deb.sh' | bash && \
apt-get update && \
apt-get install -y infisical=0.8.1
apt-get install -y infisical=0.41.2
WORKDIR /app

View File

@ -1,4 +1,8 @@
import RE2 from "re2";
import { TKeyStoreFactory } from "@app/keystore/keystore";
import { applyJitter } from "@app/lib/dates";
import { delay as delayMs } from "@app/lib/delay";
import { Lock } from "@app/lib/red-lock";
export const mockKeyStore = (): TKeyStoreFactory => {
@ -18,6 +22,27 @@ export const mockKeyStore = (): TKeyStoreFactory => {
delete store[key];
return 1;
},
deleteItems: async ({ pattern, batchSize = 500, delay = 1500, jitter = 200 }) => {
const regex = new RE2(`^${pattern.replace(/[-[\]/{}()+?.\\^$|]/g, "\\$&").replace(/\*/g, ".*")}$`);
let totalDeleted = 0;
const keys = Object.keys(store);
for (let i = 0; i < keys.length; i += batchSize) {
const batch = keys.slice(i, i + batchSize);
for (const key of batch) {
if (regex.test(key)) {
delete store[key];
totalDeleted += 1;
}
}
// eslint-disable-next-line no-await-in-loop
await delayMs(Math.max(0, applyJitter(delay, jitter)));
}
return totalDeleted;
},
getItem: async (key) => {
const value = store[key];
if (typeof value === "string") {

View File

@ -15,8 +15,8 @@ import { mockSmtpServer } from "./mocks/smtp";
import { initDbConnection } from "@app/db";
import { queueServiceFactory } from "@app/queue";
import { keyStoreFactory } from "@app/keystore/keystore";
import { Redis } from "ioredis";
import { initializeHsmModule } from "@app/ee/services/hsm/hsm-fns";
import { buildRedisFromConfig } from "@app/lib/config/redis";
dotenv.config({ path: path.join(__dirname, "../../.env.test"), debug: true });
export default {
@ -30,7 +30,7 @@ export default {
dbRootCert: envConfig.DB_ROOT_CERT
});
const redis = new Redis(envConfig.REDIS_URL);
const redis = buildRedisFromConfig(envConfig);
await redis.flushdb("SYNC");
try {
@ -55,8 +55,8 @@ export default {
});
const smtp = mockSmtpServer();
const queue = queueServiceFactory(envConfig.REDIS_URL, { dbConnectionUrl: envConfig.DB_CONNECTION_URI });
const keyStore = keyStoreFactory(envConfig.REDIS_URL);
const queue = queueServiceFactory(envConfig, { dbConnectionUrl: envConfig.DB_CONNECTION_URI });
const keyStore = keyStoreFactory(envConfig);
const hsmModule = initializeHsmModule(envConfig);
hsmModule.initialize();

7188
backend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -38,8 +38,8 @@
"build:frontend": "npm run build --prefix ../frontend",
"start": "node --enable-source-maps dist/main.mjs",
"type:check": "tsc --noEmit",
"lint:fix": "eslint --fix --ext js,ts ./src",
"lint": "eslint 'src/**/*.ts'",
"lint:fix": "node --max-old-space-size=8192 ./node_modules/.bin/eslint --fix --ext js,ts ./src",
"lint": "node --max-old-space-size=8192 ./node_modules/.bin/eslint 'src/**/*.ts'",
"test:unit": "vitest run -c vitest.unit.config.ts",
"test:e2e": "vitest run -c vitest.e2e.config.ts --bail=1",
"test:e2e-watch": "vitest -c vitest.e2e.config.ts --bail=1",
@ -72,7 +72,8 @@
"seed:new": "tsx ./scripts/create-seed-file.ts",
"seed": "knex --knexfile ./dist/db/knexfile.ts --client pg seed:run",
"seed-dev": "knex --knexfile ./src/db/knexfile.ts --client pg seed:run",
"db:reset": "npm run migration:rollback -- --all && npm run migration:latest"
"db:reset": "npm run migration:rollback -- --all && npm run migration:latest",
"email:dev": "email dev --dir src/services/smtp/emails"
},
"keywords": [],
"author": "",
@ -91,12 +92,12 @@
"@types/lodash.isequal": "^4.5.8",
"@types/node": "^20.17.30",
"@types/nodemailer": "^6.4.14",
"@types/passport-github": "^1.1.12",
"@types/passport-google-oauth20": "^2.0.14",
"@types/pg": "^8.10.9",
"@types/picomatch": "^2.3.3",
"@types/pkcs11js": "^1.0.4",
"@types/prompt-sync": "^4.2.3",
"@types/react": "^19.1.2",
"@types/resolve": "^1.20.6",
"@types/safe-regex": "^1.1.6",
"@types/sjcl": "^1.0.34",
@ -116,6 +117,7 @@
"nodemon": "^3.0.2",
"pino-pretty": "^10.2.3",
"prompt-sync": "^4.2.0",
"react-email": "4.0.7",
"rimraf": "^5.0.5",
"ts-node": "^10.9.2",
"tsc-alias": "^1.8.8",
@ -129,6 +131,7 @@
"@aws-sdk/client-elasticache": "^3.637.0",
"@aws-sdk/client-iam": "^3.525.0",
"@aws-sdk/client-kms": "^3.609.0",
"@aws-sdk/client-route-53": "^3.810.0",
"@aws-sdk/client-secrets-manager": "^3.504.0",
"@aws-sdk/client-sts": "^3.600.0",
"@casl/ability": "^6.5.0",
@ -150,6 +153,8 @@
"@infisical/quic": "^1.0.8",
"@node-saml/passport-saml": "^5.0.1",
"@octokit/auth-app": "^7.1.1",
"@octokit/core": "^5.2.1",
"@octokit/plugin-paginate-graphql": "^4.0.1",
"@octokit/plugin-retry": "^5.0.5",
"@octokit/rest": "^20.0.2",
"@octokit/webhooks-types": "^7.3.1",
@ -164,17 +169,20 @@
"@opentelemetry/semantic-conventions": "^1.27.0",
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/x509": "^1.12.1",
"@react-email/components": "0.0.36",
"@serdnam/pino-cloudwatch-transport": "^1.0.4",
"@sindresorhus/slugify": "1.1.0",
"@slack/oauth": "^3.0.2",
"@slack/web-api": "^7.8.0",
"@ucast/mongo2js": "^1.3.4",
"acme-client": "^5.4.0",
"ajv": "^8.12.0",
"argon2": "^0.31.2",
"aws-sdk": "^2.1553.0",
"axios": "^1.6.7",
"axios-retry": "^4.0.0",
"bcrypt": "^5.1.1",
"botbuilder": "^4.23.2",
"bullmq": "^5.4.2",
"cassandra-driver": "^4.7.2",
"connect-redis": "^7.1.1",
@ -203,15 +211,16 @@
"mysql2": "^3.9.8",
"nanoid": "^3.3.8",
"nodemailer": "^6.9.9",
"oci-sdk": "^2.108.0",
"odbc": "^2.4.9",
"openid-client": "^5.6.5",
"ora": "^7.0.1",
"oracledb": "^6.4.0",
"otplib": "^12.0.1",
"passport-github": "^1.1.0",
"passport-gitlab2": "^5.0.0",
"passport-google-oauth20": "^2.0.0",
"passport-ldapauth": "^3.0.1",
"passport-oauth2": "^1.8.0",
"pg": "^8.11.3",
"pg-boss": "^10.1.5",
"pg-query-stream": "^4.5.3",
@ -222,6 +231,8 @@
"posthog-node": "^3.6.2",
"probot": "^13.3.8",
"re2": "^1.21.4",
"react": "19.1.0",
"react-dom": "19.1.0",
"safe-regex": "^2.1.1",
"scim-patch": "^0.8.3",
"scim2-parse-filter": "^0.2.10",
@ -233,6 +244,6 @@
"tweetnacl-util": "^0.15.1",
"uuid": "^9.0.1",
"zod": "^3.22.4",
"zod-to-json-schema": "^3.22.4"
"zod-to-json-schema": "^3.24.5"
}
}

View File

@ -5,6 +5,7 @@ import { Redis } from "ioredis";
import { TUsers } from "@app/db/schemas";
import { TAccessApprovalPolicyServiceFactory } from "@app/ee/services/access-approval-policy/access-approval-policy-service";
import { TAccessApprovalRequestServiceFactory } from "@app/ee/services/access-approval-request/access-approval-request-service";
import { TAssumePrivilegeServiceFactory } from "@app/ee/services/assume-privilege/assume-privilege-service";
import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service";
import { TCreateAuditLogDTO } from "@app/ee/services/audit-log/audit-log-types";
import { TAuditLogStreamServiceFactory } from "@app/ee/services/audit-log-stream/audit-log-stream-service";
@ -14,6 +15,7 @@ import { TDynamicSecretServiceFactory } from "@app/ee/services/dynamic-secret/dy
import { TDynamicSecretLeaseServiceFactory } from "@app/ee/services/dynamic-secret-lease/dynamic-secret-lease-service";
import { TExternalKmsServiceFactory } from "@app/ee/services/external-kms/external-kms-service";
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
import { TGithubOrgSyncServiceFactory } from "@app/ee/services/github-org-sync/github-org-sync-service";
import { TGroupServiceFactory } from "@app/ee/services/group/group-service";
import { TIdentityProjectAdditionalPrivilegeServiceFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service";
import { TIdentityProjectAdditionalPrivilegeV2ServiceFactory } from "@app/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service";
@ -39,6 +41,7 @@ import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/
import { TSshCertificateAuthorityServiceFactory } from "@app/ee/services/ssh/ssh-certificate-authority-service";
import { TSshCertificateTemplateServiceFactory } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-service";
import { TSshHostServiceFactory } from "@app/ee/services/ssh-host/ssh-host-service";
import { TSshHostGroupServiceFactory } from "@app/ee/services/ssh-host-group/ssh-host-group-service";
import { TTrustedIpServiceFactory } from "@app/ee/services/trusted-ip/trusted-ip-service";
import { TAuthMode } from "@app/server/plugins/auth/inject-identity";
import { TApiKeyServiceFactory } from "@app/services/api-key/api-key-service";
@ -50,6 +53,7 @@ import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service";
import { TCertificateServiceFactory } from "@app/services/certificate/certificate-service";
import { TCertificateAuthorityServiceFactory } from "@app/services/certificate-authority/certificate-authority-service";
import { TInternalCertificateAuthorityServiceFactory } from "@app/services/certificate-authority/internal/internal-certificate-authority-service";
import { TCertificateTemplateServiceFactory } from "@app/services/certificate-template/certificate-template-service";
import { TCmekServiceFactory } from "@app/services/cmek/cmek-service";
import { TExternalGroupOrgRoleMappingServiceFactory } from "@app/services/external-group-org-role-mapping/external-group-org-role-mapping-service";
@ -63,17 +67,22 @@ import { TIdentityAzureAuthServiceFactory } from "@app/services/identity-azure-a
import { TIdentityGcpAuthServiceFactory } from "@app/services/identity-gcp-auth/identity-gcp-auth-service";
import { TIdentityJwtAuthServiceFactory } from "@app/services/identity-jwt-auth/identity-jwt-auth-service";
import { TIdentityKubernetesAuthServiceFactory } from "@app/services/identity-kubernetes-auth/identity-kubernetes-auth-service";
import { TIdentityLdapAuthServiceFactory } from "@app/services/identity-ldap-auth/identity-ldap-auth-service";
import { TAllowedFields } from "@app/services/identity-ldap-auth/identity-ldap-auth-types";
import { TIdentityOciAuthServiceFactory } from "@app/services/identity-oci-auth/identity-oci-auth-service";
import { TIdentityOidcAuthServiceFactory } from "@app/services/identity-oidc-auth/identity-oidc-auth-service";
import { TIdentityProjectServiceFactory } from "@app/services/identity-project/identity-project-service";
import { TIdentityTokenAuthServiceFactory } from "@app/services/identity-token-auth/identity-token-auth-service";
import { TIdentityUaServiceFactory } from "@app/services/identity-ua/identity-ua-service";
import { TIntegrationServiceFactory } from "@app/services/integration/integration-service";
import { TIntegrationAuthServiceFactory } from "@app/services/integration-auth/integration-auth-service";
import { TMicrosoftTeamsServiceFactory } from "@app/services/microsoft-teams/microsoft-teams-service";
import { TOrgRoleServiceFactory } from "@app/services/org/org-role-service";
import { TOrgServiceFactory } from "@app/services/org/org-service";
import { TOrgAdminServiceFactory } from "@app/services/org-admin/org-admin-service";
import { TPkiAlertServiceFactory } from "@app/services/pki-alert/pki-alert-service";
import { TPkiCollectionServiceFactory } from "@app/services/pki-collection/pki-collection-service";
import { TPkiSubscriberServiceFactory } from "@app/services/pki-subscriber/pki-subscriber-service";
import { TProjectServiceFactory } from "@app/services/project/project-service";
import { TProjectBotServiceFactory } from "@app/services/project-bot/project-bot-service";
import { TProjectEnvServiceFactory } from "@app/services/project-env/project-env-service";
@ -102,6 +111,7 @@ import { TWorkflowIntegrationServiceFactory } from "@app/services/workflow-integ
declare module "@fastify/request-context" {
interface RequestContextData {
reqId: string;
orgId?: string;
identityAuthInfo?: {
identityId: string;
oidc?: {
@ -109,12 +119,14 @@ declare module "@fastify/request-context" {
};
};
identityPermissionMetadata?: Record<string, unknown>; // filled by permission service
assumedPrivilegeDetails?: { requesterId: string; actorId: string; actorType: ActorType; projectId: string };
}
}
declare module "fastify" {
interface Session {
callbackPort: string;
isAdminLogin: boolean;
}
interface FastifyRequest {
@ -138,6 +150,14 @@ declare module "fastify" {
passportUser: {
isUserCompleted: boolean;
providerAuthToken: string;
externalProviderAccessToken?: string;
};
passportMachineIdentity: {
identityId: string;
user: {
uid: string;
mail?: string;
};
};
kmipUser: {
projectId: string;
@ -146,7 +166,9 @@ declare module "fastify" {
};
auditLogInfo: Pick<TCreateAuditLogDTO, "userAgent" | "userAgentType" | "ipAddress" | "actor">;
ssoConfig: Awaited<ReturnType<TSamlConfigServiceFactory["getSaml"]>>;
ldapConfig: Awaited<ReturnType<TLdapConfigServiceFactory["getLdapCfg"]>>;
ldapConfig: Awaited<ReturnType<TLdapConfigServiceFactory["getLdapCfg"]>> & {
allowedFields?: TAllowedFields[];
};
}
interface FastifyInstance {
@ -190,8 +212,10 @@ declare module "fastify" {
identityGcpAuth: TIdentityGcpAuthServiceFactory;
identityAwsAuth: TIdentityAwsAuthServiceFactory;
identityAzureAuth: TIdentityAzureAuthServiceFactory;
identityOciAuth: TIdentityOciAuthServiceFactory;
identityOidcAuth: TIdentityOidcAuthServiceFactory;
identityJwtAuth: TIdentityJwtAuthServiceFactory;
identityLdapAuth: TIdentityLdapAuthServiceFactory;
accessApprovalPolicy: TAccessApprovalPolicyServiceFactory;
accessApprovalRequest: TAccessApprovalRequestServiceFactory;
secretApprovalPolicy: TSecretApprovalPolicyServiceFactory;
@ -208,10 +232,12 @@ declare module "fastify" {
sshCertificateAuthority: TSshCertificateAuthorityServiceFactory;
sshCertificateTemplate: TSshCertificateTemplateServiceFactory;
sshHost: TSshHostServiceFactory;
sshHostGroup: TSshHostGroupServiceFactory;
certificateAuthority: TCertificateAuthorityServiceFactory;
certificateAuthorityCrl: TCertificateAuthorityCrlServiceFactory;
certificateEst: TCertificateEstServiceFactory;
pkiCollection: TPkiCollectionServiceFactory;
pkiSubscriber: TPkiSubscriberServiceFactory;
secretScanning: TSecretScanningServiceFactory;
license: TLicenseServiceFactory;
trustedIp: TTrustedIpServiceFactory;
@ -241,6 +267,10 @@ declare module "fastify" {
kmipOperation: TKmipOperationServiceFactory;
gateway: TGatewayServiceFactory;
secretRotationV2: TSecretRotationV2ServiceFactory;
microsoftTeams: TMicrosoftTeamsServiceFactory;
assumePrivileges: TAssumePrivilegeServiceFactory;
githubOrgSync: TGithubOrgSyncServiceFactory;
internalCertificateAuthority: TInternalCertificateAuthorityServiceFactory;
};
// this is exclusive use for middlewares in which we need to inject data
// everywhere else access using service layer

View File

@ -68,6 +68,9 @@ import {
TDynamicSecrets,
TDynamicSecretsInsert,
TDynamicSecretsUpdate,
TExternalCertificateAuthorities,
TExternalCertificateAuthoritiesInsert,
TExternalCertificateAuthoritiesUpdate,
TExternalGroupOrgRoleMappings,
TExternalGroupOrgRoleMappingsInsert,
TExternalGroupOrgRoleMappingsUpdate,
@ -83,6 +86,9 @@ import {
TGitAppOrg,
TGitAppOrgInsert,
TGitAppOrgUpdate,
TGithubOrgSyncConfigs,
TGithubOrgSyncConfigsInsert,
TGithubOrgSyncConfigsUpdate,
TGroupProjectMembershipRoles,
TGroupProjectMembershipRolesInsert,
TGroupProjectMembershipRolesUpdate,
@ -116,6 +122,9 @@ import {
TIdentityMetadata,
TIdentityMetadataInsert,
TIdentityMetadataUpdate,
TIdentityOciAuths,
TIdentityOciAuthsInsert,
TIdentityOciAuthsUpdate,
TIdentityOidcAuths,
TIdentityOidcAuthsInsert,
TIdentityOidcAuthsUpdate,
@ -149,6 +158,9 @@ import {
TIntegrations,
TIntegrationsInsert,
TIntegrationsUpdate,
TInternalCertificateAuthorities,
TInternalCertificateAuthoritiesInsert,
TInternalCertificateAuthoritiesUpdate,
TInternalKms,
TInternalKmsInsert,
TInternalKmsUpdate,
@ -206,6 +218,9 @@ import {
TPkiCollections,
TPkiCollectionsInsert,
TPkiCollectionsUpdate,
TPkiSubscribers,
TPkiSubscribersInsert,
TPkiSubscribersUpdate,
TProjectBots,
TProjectBotsInsert,
TProjectBotsUpdate,
@ -383,6 +398,12 @@ import {
TSshCertificateTemplates,
TSshCertificateTemplatesInsert,
TSshCertificateTemplatesUpdate,
TSshHostGroupMemberships,
TSshHostGroupMembershipsInsert,
TSshHostGroupMembershipsUpdate,
TSshHostGroups,
TSshHostGroupsInsert,
TSshHostGroupsUpdate,
TSshHostLoginUserMappings,
TSshHostLoginUserMappingsInsert,
TSshHostLoginUserMappingsUpdate,
@ -423,6 +444,26 @@ import {
TWorkflowIntegrationsInsert,
TWorkflowIntegrationsUpdate
} from "@app/db/schemas";
import {
TIdentityLdapAuths,
TIdentityLdapAuthsInsert,
TIdentityLdapAuthsUpdate
} from "@app/db/schemas/identity-ldap-auths";
import {
TMicrosoftTeamsIntegrations,
TMicrosoftTeamsIntegrationsInsert,
TMicrosoftTeamsIntegrationsUpdate
} from "@app/db/schemas/microsoft-teams-integrations";
import {
TProjectMicrosoftTeamsConfigs,
TProjectMicrosoftTeamsConfigsInsert,
TProjectMicrosoftTeamsConfigsUpdate
} from "@app/db/schemas/project-microsoft-teams-configs";
import {
TSecretReminderRecipients,
TSecretReminderRecipientsInsert,
TSecretReminderRecipientsUpdate
} from "@app/db/schemas/secret-reminder-recipients";
declare module "knex" {
namespace Knex {
@ -437,6 +478,16 @@ declare module "knex/types/tables" {
interface Tables {
[TableName.Users]: KnexOriginal.CompositeTableType<TUsers, TUsersInsert, TUsersUpdate>;
[TableName.Groups]: KnexOriginal.CompositeTableType<TGroups, TGroupsInsert, TGroupsUpdate>;
[TableName.SshHostGroup]: KnexOriginal.CompositeTableType<
TSshHostGroups,
TSshHostGroupsInsert,
TSshHostGroupsUpdate
>;
[TableName.SshHostGroupMembership]: KnexOriginal.CompositeTableType<
TSshHostGroupMemberships,
TSshHostGroupMembershipsInsert,
TSshHostGroupMembershipsUpdate
>;
[TableName.SshHost]: KnexOriginal.CompositeTableType<TSshHosts, TSshHostsInsert, TSshHostsUpdate>;
[TableName.SshCertificateAuthority]: KnexOriginal.CompositeTableType<
TSshCertificateAuthorities,
@ -493,6 +544,16 @@ declare module "knex/types/tables" {
TCertificateAuthorityCrlInsert,
TCertificateAuthorityCrlUpdate
>;
[TableName.InternalCertificateAuthority]: KnexOriginal.CompositeTableType<
TInternalCertificateAuthorities,
TInternalCertificateAuthoritiesInsert,
TInternalCertificateAuthoritiesUpdate
>;
[TableName.ExternalCertificateAuthority]: KnexOriginal.CompositeTableType<
TExternalCertificateAuthorities,
TExternalCertificateAuthoritiesInsert,
TExternalCertificateAuthoritiesUpdate
>;
[TableName.Certificate]: KnexOriginal.CompositeTableType<TCertificates, TCertificatesInsert, TCertificatesUpdate>;
[TableName.CertificateTemplate]: KnexOriginal.CompositeTableType<
TCertificateTemplates,
@ -525,6 +586,11 @@ declare module "knex/types/tables" {
TPkiCollectionItemsInsert,
TPkiCollectionItemsUpdate
>;
[TableName.PkiSubscriber]: KnexOriginal.CompositeTableType<
TPkiSubscribers,
TPkiSubscribersInsert,
TPkiSubscribersUpdate
>;
[TableName.UserGroupMembership]: KnexOriginal.CompositeTableType<
TUserGroupMembership,
TUserGroupMembershipInsert,
@ -691,6 +757,11 @@ declare module "knex/types/tables" {
TIdentityAzureAuthsInsert,
TIdentityAzureAuthsUpdate
>;
[TableName.IdentityOciAuth]: KnexOriginal.CompositeTableType<
TIdentityOciAuths,
TIdentityOciAuthsInsert,
TIdentityOciAuthsUpdate
>;
[TableName.IdentityOidcAuth]: KnexOriginal.CompositeTableType<
TIdentityOidcAuths,
TIdentityOidcAuthsInsert,
@ -701,6 +772,11 @@ declare module "knex/types/tables" {
TIdentityJwtAuthsInsert,
TIdentityJwtAuthsUpdate
>;
[TableName.IdentityLdapAuth]: KnexOriginal.CompositeTableType<
TIdentityLdapAuths,
TIdentityLdapAuthsInsert,
TIdentityLdapAuthsUpdate
>;
[TableName.IdentityUaClientSecret]: KnexOriginal.CompositeTableType<
TIdentityUaClientSecrets,
TIdentityUaClientSecretsInsert,
@ -994,5 +1070,25 @@ declare module "knex/types/tables" {
TSecretRotationV2SecretMappingsInsert,
TSecretRotationV2SecretMappingsUpdate
>;
[TableName.MicrosoftTeamsIntegrations]: KnexOriginal.CompositeTableType<
TMicrosoftTeamsIntegrations,
TMicrosoftTeamsIntegrationsInsert,
TMicrosoftTeamsIntegrationsUpdate
>;
[TableName.ProjectMicrosoftTeamsConfigs]: KnexOriginal.CompositeTableType<
TProjectMicrosoftTeamsConfigs,
TProjectMicrosoftTeamsConfigsInsert,
TProjectMicrosoftTeamsConfigsUpdate
>;
[TableName.SecretReminderRecipients]: KnexOriginal.CompositeTableType<
TSecretReminderRecipients,
TSecretReminderRecipientsInsert,
TSecretReminderRecipientsUpdate
>;
[TableName.GithubOrgSyncConfig]: KnexOriginal.CompositeTableType<
TGithubOrgSyncConfigs,
TGithubOrgSyncConfigsInsert,
TGithubOrgSyncConfigsUpdate
>;
}
}

View File

@ -0,0 +1,34 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
const hasSecretReminderRecipientsTable = await knex.schema.hasTable(TableName.SecretReminderRecipients);
if (!hasSecretReminderRecipientsTable) {
await knex.schema.createTable(TableName.SecretReminderRecipients, (table) => {
table.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
table.timestamps(true, true, true);
table.uuid("secretId").notNullable();
table.uuid("userId").notNullable();
table.string("projectId").notNullable();
// Based on userId rather than project membership ID so we can easily extend group support in the future if need be.
// This does however mean we need to manually clean up once a user is removed from a project.
table.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE");
table.foreign("secretId").references("id").inTable(TableName.SecretV2).onDelete("CASCADE");
table.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE");
table.index("secretId");
table.unique(["secretId", "userId"]);
});
}
}
export async function down(knex: Knex): Promise<void> {
const hasSecretReminderRecipientsTable = await knex.schema.hasTable(TableName.SecretReminderRecipients);
if (hasSecretReminderRecipientsTable) {
await knex.schema.dropTableIfExists(TableName.SecretReminderRecipients);
}
}

View File

@ -0,0 +1,130 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
const superAdminHasEncryptedMicrosoftTeamsClientIdColumn = await knex.schema.hasColumn(
TableName.SuperAdmin,
"encryptedMicrosoftTeamsAppId"
);
const superAdminHasEncryptedMicrosoftTeamsClientSecret = await knex.schema.hasColumn(
TableName.SuperAdmin,
"encryptedMicrosoftTeamsClientSecret"
);
const superAdminHasEncryptedMicrosoftTeamsBotId = await knex.schema.hasColumn(
TableName.SuperAdmin,
"encryptedMicrosoftTeamsBotId"
);
if (
!superAdminHasEncryptedMicrosoftTeamsClientIdColumn ||
!superAdminHasEncryptedMicrosoftTeamsClientSecret ||
!superAdminHasEncryptedMicrosoftTeamsBotId
) {
await knex.schema.alterTable(TableName.SuperAdmin, (table) => {
if (!superAdminHasEncryptedMicrosoftTeamsClientIdColumn) {
table.binary("encryptedMicrosoftTeamsAppId").nullable();
}
if (!superAdminHasEncryptedMicrosoftTeamsClientSecret) {
table.binary("encryptedMicrosoftTeamsClientSecret").nullable();
}
if (!superAdminHasEncryptedMicrosoftTeamsBotId) {
table.binary("encryptedMicrosoftTeamsBotId").nullable();
}
});
}
if (!(await knex.schema.hasColumn(TableName.WorkflowIntegrations, "status"))) {
await knex.schema.alterTable(TableName.WorkflowIntegrations, (table) => {
table.enu("status", ["pending", "installed", "failed"]).notNullable().defaultTo("installed"); // defaults to installed so we can have backwards compatibility with existing workflow integrations
});
}
if (!(await knex.schema.hasTable(TableName.MicrosoftTeamsIntegrations))) {
await knex.schema.createTable(TableName.MicrosoftTeamsIntegrations, (table) => {
table.uuid("id", { primaryKey: true }).notNullable();
table.foreign("id").references("id").inTable(TableName.WorkflowIntegrations).onDelete("CASCADE"); // the ID itself is the workflow integration ID
table.string("internalTeamsAppId").nullable();
table.string("tenantId").notNullable();
table.binary("encryptedAccessToken").nullable();
table.binary("encryptedBotAccessToken").nullable();
table.timestamp("accessTokenExpiresAt").nullable();
table.timestamp("botAccessTokenExpiresAt").nullable();
table.timestamps(true, true, true);
});
await createOnUpdateTrigger(knex, TableName.MicrosoftTeamsIntegrations);
}
if (!(await knex.schema.hasTable(TableName.ProjectMicrosoftTeamsConfigs))) {
await knex.schema.createTable(TableName.ProjectMicrosoftTeamsConfigs, (tb) => {
tb.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
tb.string("projectId").notNullable().unique();
tb.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE");
tb.uuid("microsoftTeamsIntegrationId").notNullable();
tb.foreign("microsoftTeamsIntegrationId")
.references("id")
.inTable(TableName.MicrosoftTeamsIntegrations)
.onDelete("CASCADE");
tb.boolean("isAccessRequestNotificationEnabled").notNullable().defaultTo(false);
tb.boolean("isSecretRequestNotificationEnabled").notNullable().defaultTo(false);
tb.jsonb("accessRequestChannels").notNullable(); // {teamId: string, channelIds: string[]}
tb.jsonb("secretRequestChannels").notNullable(); // {teamId: string, channelIds: string[]}
tb.timestamps(true, true, true);
});
await createOnUpdateTrigger(knex, TableName.ProjectMicrosoftTeamsConfigs);
}
}
export async function down(knex: Knex): Promise<void> {
const hasEncryptedMicrosoftTeamsClientIdColumn = await knex.schema.hasColumn(
TableName.SuperAdmin,
"encryptedMicrosoftTeamsAppId"
);
const hasEncryptedMicrosoftTeamsClientSecret = await knex.schema.hasColumn(
TableName.SuperAdmin,
"encryptedMicrosoftTeamsClientSecret"
);
const hasEncryptedMicrosoftTeamsBotId = await knex.schema.hasColumn(
TableName.SuperAdmin,
"encryptedMicrosoftTeamsBotId"
);
if (
hasEncryptedMicrosoftTeamsClientIdColumn ||
hasEncryptedMicrosoftTeamsClientSecret ||
hasEncryptedMicrosoftTeamsBotId
) {
await knex.schema.alterTable(TableName.SuperAdmin, (table) => {
if (hasEncryptedMicrosoftTeamsClientIdColumn) {
table.dropColumn("encryptedMicrosoftTeamsAppId");
}
if (hasEncryptedMicrosoftTeamsClientSecret) {
table.dropColumn("encryptedMicrosoftTeamsClientSecret");
}
if (hasEncryptedMicrosoftTeamsBotId) {
table.dropColumn("encryptedMicrosoftTeamsBotId");
}
});
}
if (await knex.schema.hasColumn(TableName.WorkflowIntegrations, "status")) {
await knex.schema.alterTable(TableName.WorkflowIntegrations, (table) => {
table.dropColumn("status");
});
}
if (await knex.schema.hasTable(TableName.ProjectMicrosoftTeamsConfigs)) {
await knex.schema.dropTableIfExists(TableName.ProjectMicrosoftTeamsConfigs);
await dropOnUpdateTrigger(knex, TableName.ProjectMicrosoftTeamsConfigs);
}
if (await knex.schema.hasTable(TableName.MicrosoftTeamsIntegrations)) {
await knex.schema.dropTableIfExists(TableName.MicrosoftTeamsIntegrations);
await dropOnUpdateTrigger(knex, TableName.MicrosoftTeamsIntegrations);
}
}

View File

@ -0,0 +1,23 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
const hasAliasColumn = await knex.schema.hasColumn(TableName.SshHost, "alias");
if (!hasAliasColumn) {
await knex.schema.alterTable(TableName.SshHost, (t) => {
t.string("alias").nullable();
t.unique(["projectId", "alias"]);
});
}
}
export async function down(knex: Knex): Promise<void> {
const hasAliasColumn = await knex.schema.hasColumn(TableName.SshHost, "alias");
if (hasAliasColumn) {
await knex.schema.alterTable(TableName.SshHost, (t) => {
t.dropUnique(["projectId", "alias"]);
t.dropColumn("alias");
});
}
}

View File

@ -0,0 +1,26 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
const hasTable = await knex.schema.hasTable(TableName.GithubOrgSyncConfig);
if (!hasTable) {
await knex.schema.createTable(TableName.GithubOrgSyncConfig, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.string("githubOrgName").notNullable();
t.boolean("isActive").defaultTo(false);
t.binary("encryptedGithubOrgAccessToken");
t.uuid("orgId").notNullable().unique();
t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE");
t.timestamps(true, true, true);
});
}
await createOnUpdateTrigger(knex, TableName.GithubOrgSyncConfig);
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTableIfExists(TableName.GithubOrgSyncConfig);
await dropOnUpdateTrigger(knex, TableName.GithubOrgSyncConfig);
}

View File

@ -0,0 +1,27 @@
import { Knex } from "knex";
import { getConfig } from "@app/lib/config/env";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
const appCfg = getConfig();
const tokenDuration = appCfg?.JWT_REFRESH_LIFETIME;
if (!(await knex.schema.hasColumn(TableName.Organization, "userTokenExpiration"))) {
await knex.schema.alterTable(TableName.Organization, (t) => {
t.string("userTokenExpiration");
});
if (tokenDuration) {
await knex(TableName.Organization).update({ userTokenExpiration: tokenDuration });
}
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasColumn(TableName.Organization, "userTokenExpiration")) {
await knex.schema.alterTable(TableName.Organization, (t) => {
t.dropColumn("userTokenExpiration");
});
}
}

View File

@ -0,0 +1,55 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.SshHostGroup))) {
await knex.schema.createTable(TableName.SshHostGroup, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
t.string("projectId").notNullable();
t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE");
t.string("name").notNullable();
t.unique(["projectId", "name"]);
});
await createOnUpdateTrigger(knex, TableName.SshHostGroup);
}
if (!(await knex.schema.hasTable(TableName.SshHostGroupMembership))) {
await knex.schema.createTable(TableName.SshHostGroupMembership, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
t.uuid("sshHostGroupId").notNullable();
t.foreign("sshHostGroupId").references("id").inTable(TableName.SshHostGroup).onDelete("CASCADE");
t.uuid("sshHostId").notNullable();
t.foreign("sshHostId").references("id").inTable(TableName.SshHost).onDelete("CASCADE");
t.unique(["sshHostGroupId", "sshHostId"]);
});
await createOnUpdateTrigger(knex, TableName.SshHostGroupMembership);
}
const hasGroupColumn = await knex.schema.hasColumn(TableName.SshHostLoginUser, "sshHostGroupId");
if (!hasGroupColumn) {
await knex.schema.alterTable(TableName.SshHostLoginUser, (t) => {
t.uuid("sshHostGroupId").nullable();
t.foreign("sshHostGroupId").references("id").inTable(TableName.SshHostGroup).onDelete("CASCADE");
t.uuid("sshHostId").nullable().alter();
});
}
}
export async function down(knex: Knex): Promise<void> {
const hasGroupColumn = await knex.schema.hasColumn(TableName.SshHostLoginUser, "sshHostGroupId");
if (hasGroupColumn) {
await knex.schema.alterTable(TableName.SshHostLoginUser, (t) => {
t.dropColumn("sshHostGroupId");
});
}
await knex.schema.dropTableIfExists(TableName.SshHostGroupMembership);
await dropOnUpdateTrigger(knex, TableName.SshHostGroupMembership);
await knex.schema.dropTableIfExists(TableName.SshHostGroup);
await dropOnUpdateTrigger(knex, TableName.SshHostGroup);
}

View File

@ -0,0 +1,44 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (await knex.schema.hasTable(TableName.Certificate)) {
const hasProjectIdColumn = await knex.schema.hasColumn(TableName.Certificate, "projectId");
if (!hasProjectIdColumn) {
await knex.schema.alterTable(TableName.Certificate, (t) => {
t.string("projectId", 36).nullable();
t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE");
});
await knex.raw(`
UPDATE "${TableName.Certificate}" cert
SET "projectId" = ca."projectId"
FROM "${TableName.CertificateAuthority}" ca
WHERE cert."caId" = ca.id
`);
await knex.schema.alterTable(TableName.Certificate, (t) => {
t.string("projectId").notNullable().alter();
});
}
await knex.schema.alterTable(TableName.Certificate, (t) => {
t.uuid("caId").nullable().alter();
t.uuid("caCertId").nullable().alter();
});
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasTable(TableName.Certificate)) {
if (await knex.schema.hasColumn(TableName.Certificate, "projectId")) {
await knex.schema.alterTable(TableName.Certificate, (t) => {
t.dropForeign("projectId");
t.dropColumn("projectId");
});
}
}
// Altering back to notNullable for caId and caCertId will fail
}

View File

@ -0,0 +1,33 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasColumn(TableName.CertificateBody, "encryptedCertificateChain"))) {
await knex.schema.alterTable(TableName.CertificateBody, (t) => {
t.binary("encryptedCertificateChain").nullable();
});
}
if (!(await knex.schema.hasTable(TableName.CertificateSecret))) {
await knex.schema.createTable(TableName.CertificateSecret, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
t.uuid("certId").notNullable().unique();
t.foreign("certId").references("id").inTable(TableName.Certificate).onDelete("CASCADE");
t.binary("encryptedPrivateKey").notNullable();
});
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasTable(TableName.CertificateSecret)) {
await knex.schema.dropTable(TableName.CertificateSecret);
}
if (await knex.schema.hasColumn(TableName.CertificateBody, "encryptedCertificateChain")) {
await knex.schema.alterTable(TableName.CertificateBody, (t) => {
t.dropColumn("encryptedCertificateChain");
});
}
}

View File

@ -0,0 +1,47 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
const hasEmail = await knex.schema.hasColumn(TableName.Users, "email");
const hasUsername = await knex.schema.hasColumn(TableName.Users, "username");
if (hasEmail) {
await knex(TableName.Users)
.where({ isGhost: false })
.update({
// @ts-expect-error email assume string this is expected
email: knex.raw("lower(email)")
});
}
if (hasUsername) {
await knex.schema.raw(`
CREATE INDEX IF NOT EXISTS ${TableName.Users}_lower_username_idx
ON ${TableName.Users} (LOWER(username))
`);
const duplicatesSubquery = knex(TableName.Users)
.select(knex.raw("lower(username) as lowercase_username"))
.groupBy("lowercase_username")
.having(knex.raw("count(*)"), ">", 1);
// Update usernames to lowercase where they won't create duplicates
await knex(TableName.Users)
.where({ isGhost: false })
.whereRaw("username <> lower(username)") // Only update if not already lowercase
// @ts-expect-error username assume string this is expected
.whereNotIn(knex.raw("lower(username)"), duplicatesSubquery)
.update({
// @ts-expect-error username assume string this is expected
username: knex.raw("lower(username)")
});
}
}
export async function down(knex: Knex): Promise<void> {
const hasUsername = await knex.schema.hasColumn(TableName.Users, "username");
if (hasUsername) {
await knex.schema.raw(`
DROP INDEX IF EXISTS ${TableName.Users}_lower_username_idx
`);
}
}

View File

@ -0,0 +1,22 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasColumn(TableName.SshHostLoginUserMapping, "groupId"))) {
await knex.schema.alterTable(TableName.SshHostLoginUserMapping, (t) => {
t.uuid("groupId").nullable();
t.foreign("groupId").references("id").inTable(TableName.Groups).onDelete("CASCADE");
t.unique(["sshHostLoginUserId", "groupId"]);
});
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasColumn(TableName.SshHostLoginUserMapping, "groupId")) {
await knex.schema.alterTable(TableName.SshHostLoginUserMapping, (t) => {
t.dropUnique(["sshHostLoginUserId", "groupId"]);
t.dropColumn("groupId");
});
}
}

View File

@ -0,0 +1,22 @@
import { Knex } from "knex";
import { ProjectType, TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasColumn(TableName.ProjectTemplates, "type"))) {
await knex.schema.alterTable(TableName.ProjectTemplates, (t) => {
// defaulting to sm for migration to set existing, new ones will always be specified on creation
t.string("type").defaultTo(ProjectType.SecretManager).notNullable();
t.jsonb("environments").nullable().alter();
});
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasColumn(TableName.ProjectTemplates, "type")) {
await knex.schema.alterTable(TableName.ProjectTemplates, (t) => {
t.dropColumn("type");
// not reverting nullable environments
});
}
}

View File

@ -0,0 +1,39 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.IdentityLdapAuth))) {
await knex.schema.createTable(TableName.IdentityLdapAuth, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.bigInteger("accessTokenTTL").defaultTo(7200).notNullable();
t.bigInteger("accessTokenMaxTTL").defaultTo(7200).notNullable();
t.bigInteger("accessTokenNumUsesLimit").defaultTo(0).notNullable();
t.jsonb("accessTokenTrustedIps").notNullable();
t.uuid("identityId").notNullable().unique();
t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE");
t.binary("encryptedBindDN").notNullable();
t.binary("encryptedBindPass").notNullable();
t.binary("encryptedLdapCaCertificate").nullable();
t.string("url").notNullable();
t.string("searchBase").notNullable();
t.string("searchFilter").notNullable();
t.jsonb("allowedFields").nullable();
t.timestamps(true, true, true);
});
}
await createOnUpdateTrigger(knex, TableName.IdentityLdapAuth);
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTableIfExists(TableName.IdentityLdapAuth);
await dropOnUpdateTrigger(knex, TableName.IdentityLdapAuth);
}

View File

@ -0,0 +1,46 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.PkiSubscriber))) {
await knex.schema.createTable(TableName.PkiSubscriber, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
t.string("projectId").notNullable();
t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE");
t.uuid("caId").nullable();
t.foreign("caId").references("id").inTable(TableName.CertificateAuthority).onDelete("SET NULL");
t.string("name").notNullable();
t.string("commonName").notNullable();
t.specificType("subjectAlternativeNames", "text[]").notNullable();
t.string("ttl").notNullable();
t.specificType("keyUsages", "text[]").notNullable();
t.specificType("extendedKeyUsages", "text[]").notNullable();
t.string("status").notNullable(); // active / disabled
t.unique(["projectId", "name"]);
});
await createOnUpdateTrigger(knex, TableName.PkiSubscriber);
}
const hasSubscriberCol = await knex.schema.hasColumn(TableName.Certificate, "pkiSubscriberId");
if (!hasSubscriberCol) {
await knex.schema.alterTable(TableName.Certificate, (t) => {
t.uuid("pkiSubscriberId").nullable();
t.foreign("pkiSubscriberId").references("id").inTable(TableName.PkiSubscriber).onDelete("SET NULL");
});
}
}
export async function down(knex: Knex): Promise<void> {
const hasSubscriberCol = await knex.schema.hasColumn(TableName.Certificate, "pkiSubscriberId");
if (hasSubscriberCol) {
await knex.schema.alterTable(TableName.Certificate, (t) => {
t.dropColumn("pkiSubscriberId");
});
}
await knex.schema.dropTableIfExists(TableName.PkiSubscriber);
await dropOnUpdateTrigger(knex, TableName.PkiSubscriber);
}

View File

@ -0,0 +1,30 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.IdentityOciAuth))) {
await knex.schema.createTable(TableName.IdentityOciAuth, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.bigInteger("accessTokenTTL").defaultTo(7200).notNullable();
t.bigInteger("accessTokenMaxTTL").defaultTo(7200).notNullable();
t.bigInteger("accessTokenNumUsesLimit").defaultTo(0).notNullable();
t.jsonb("accessTokenTrustedIps").notNullable();
t.timestamps(true, true, true);
t.uuid("identityId").notNullable().unique();
t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE");
t.string("type").notNullable();
t.string("tenancyOcid").notNullable();
t.string("allowedUsernames").nullable();
});
}
await createOnUpdateTrigger(knex, TableName.IdentityOciAuth);
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTableIfExists(TableName.IdentityOciAuth);
await dropOnUpdateTrigger(knex, TableName.IdentityOciAuth);
}

View File

@ -0,0 +1,25 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
const hasGatewayIdColumn = await knex.schema.hasColumn(TableName.IdentityKubernetesAuth, "gatewayId");
if (!hasGatewayIdColumn) {
await knex.schema.alterTable(TableName.IdentityKubernetesAuth, (table) => {
table.uuid("gatewayId").nullable();
table.foreign("gatewayId").references("id").inTable(TableName.Gateway).onDelete("SET NULL");
});
}
}
export async function down(knex: Knex): Promise<void> {
const hasGatewayIdColumn = await knex.schema.hasColumn(TableName.IdentityKubernetesAuth, "gatewayId");
if (hasGatewayIdColumn) {
await knex.schema.alterTable(TableName.IdentityKubernetesAuth, (table) => {
table.dropForeign("gatewayId");
table.dropColumn("gatewayId");
});
}
}

View File

@ -0,0 +1,110 @@
import { Knex } from "knex";
import { inMemoryKeyStore } from "@app/keystore/memory";
import { selectAllTableCols } from "@app/lib/knex";
import { initLogger } from "@app/lib/logger";
import { KmsDataKey } from "@app/services/kms/kms-types";
import { TableName } from "../schemas";
import { getMigrationEnvConfig } from "./utils/env-config";
import { getMigrationEncryptionServices } from "./utils/services";
// Note(daniel): We aren't dropping tables or columns in this migrations so we can easily rollback if needed.
// In the future we need to drop the projectGatewayId on the dynamic secrets table, and drop the project_gateways table entirely.
const BATCH_SIZE = 500;
export async function up(knex: Knex): Promise<void> {
// eslint-disable-next-line no-param-reassign
knex.replicaNode = () => {
return knex;
};
if (!(await knex.schema.hasColumn(TableName.DynamicSecret, "gatewayId"))) {
await knex.schema.alterTable(TableName.DynamicSecret, (table) => {
table.uuid("gatewayId").nullable();
table.foreign("gatewayId").references("id").inTable(TableName.Gateway).onDelete("SET NULL");
table.index("gatewayId");
});
const existingDynamicSecretsWithProjectGatewayId = await knex(TableName.DynamicSecret)
.select(selectAllTableCols(TableName.DynamicSecret))
.whereNotNull(`${TableName.DynamicSecret}.projectGatewayId`)
.join(TableName.ProjectGateway, `${TableName.ProjectGateway}.id`, `${TableName.DynamicSecret}.projectGatewayId`)
.whereNotNull(`${TableName.ProjectGateway}.gatewayId`)
.select(
knex.ref("projectId").withSchema(TableName.ProjectGateway).as("projectId"),
knex.ref("gatewayId").withSchema(TableName.ProjectGateway).as("projectGatewayGatewayId")
);
initLogger();
const envConfig = getMigrationEnvConfig();
const keyStore = inMemoryKeyStore();
const { kmsService } = await getMigrationEncryptionServices({ envConfig, keyStore, db: knex });
const updatedDynamicSecrets = await Promise.all(
existingDynamicSecretsWithProjectGatewayId.map(async (existingDynamicSecret) => {
if (!existingDynamicSecret.projectGatewayGatewayId) {
const result = {
...existingDynamicSecret,
gatewayId: null
};
const { projectId, projectGatewayGatewayId, ...rest } = result;
return rest;
}
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.SecretManager,
projectId: existingDynamicSecret.projectId
});
const { encryptor: secretManagerEncryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.SecretManager,
projectId: existingDynamicSecret.projectId
});
let decryptedStoredInput = JSON.parse(
secretManagerDecryptor({ cipherTextBlob: Buffer.from(existingDynamicSecret.encryptedInput) }).toString()
) as object;
// We're not removing the existing projectGatewayId from the input so we can easily rollback without having to re-encrypt the input
decryptedStoredInput = {
...decryptedStoredInput,
gatewayId: existingDynamicSecret.projectGatewayGatewayId
};
const encryptedInput = secretManagerEncryptor({
plainText: Buffer.from(JSON.stringify(decryptedStoredInput))
}).cipherTextBlob;
const result = {
...existingDynamicSecret,
encryptedInput,
gatewayId: existingDynamicSecret.projectGatewayGatewayId
};
const { projectId, projectGatewayGatewayId, ...rest } = result;
return rest;
})
);
for (let i = 0; i < updatedDynamicSecrets.length; i += BATCH_SIZE) {
// eslint-disable-next-line no-await-in-loop
await knex(TableName.DynamicSecret)
.insert(updatedDynamicSecrets.slice(i, i + BATCH_SIZE))
.onConflict("id")
.merge();
}
}
}
export async function down(knex: Knex): Promise<void> {
// no re-encryption needed as we keep the old projectGatewayId in the input
if (await knex.schema.hasColumn(TableName.DynamicSecret, "gatewayId")) {
await knex.schema.alterTable(TableName.DynamicSecret, (table) => {
table.dropForeign("gatewayId");
table.dropColumn("gatewayId");
});
}
}

View File

@ -0,0 +1,53 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
const columns = await knex.table(TableName.Organization).columnInfo();
await knex.schema.alterTable(TableName.Organization, (t) => {
if (!columns.secretsProductEnabled) {
t.boolean("secretsProductEnabled").defaultTo(true);
}
if (!columns.pkiProductEnabled) {
t.boolean("pkiProductEnabled").defaultTo(true);
}
if (!columns.kmsProductEnabled) {
t.boolean("kmsProductEnabled").defaultTo(true);
}
if (!columns.sshProductEnabled) {
t.boolean("sshProductEnabled").defaultTo(true);
}
if (!columns.scannerProductEnabled) {
t.boolean("scannerProductEnabled").defaultTo(true);
}
if (!columns.shareSecretsProductEnabled) {
t.boolean("shareSecretsProductEnabled").defaultTo(true);
}
});
}
export async function down(knex: Knex): Promise<void> {
const columns = await knex.table(TableName.Organization).columnInfo();
await knex.schema.alterTable(TableName.Organization, (t) => {
if (columns.secretsProductEnabled) {
t.dropColumn("secretsProductEnabled");
}
if (columns.pkiProductEnabled) {
t.dropColumn("pkiProductEnabled");
}
if (columns.kmsProductEnabled) {
t.dropColumn("kmsProductEnabled");
}
if (columns.sshProductEnabled) {
t.dropColumn("sshProductEnabled");
}
if (columns.scannerProductEnabled) {
t.dropColumn("scannerProductEnabled");
}
if (columns.shareSecretsProductEnabled) {
t.dropColumn("shareSecretsProductEnabled");
}
});
}

View File

@ -0,0 +1,21 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
const hasSecretSharingColumn = await knex.schema.hasColumn(TableName.Project, "secretSharing");
if (!hasSecretSharingColumn) {
await knex.schema.table(TableName.Project, (table) => {
table.boolean("secretSharing").notNullable().defaultTo(true);
});
}
}
export async function down(knex: Knex): Promise<void> {
const hasSecretSharingColumn = await knex.schema.hasColumn(TableName.Project, "secretSharing");
if (hasSecretSharingColumn) {
await knex.schema.table(TableName.Project, (table) => {
table.dropColumn("secretSharing");
});
}
}

View File

@ -0,0 +1,35 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
const hasLifetimeColumn = await knex.schema.hasColumn(TableName.Organization, "maxSharedSecretLifetime");
const hasViewLimitColumn = await knex.schema.hasColumn(TableName.Organization, "maxSharedSecretViewLimit");
if (!hasLifetimeColumn || !hasViewLimitColumn) {
await knex.schema.alterTable(TableName.Organization, (t) => {
if (!hasLifetimeColumn) {
t.integer("maxSharedSecretLifetime").nullable().defaultTo(2592000); // 30 days in seconds
}
if (!hasViewLimitColumn) {
t.integer("maxSharedSecretViewLimit").nullable();
}
});
}
}
export async function down(knex: Knex): Promise<void> {
const hasLifetimeColumn = await knex.schema.hasColumn(TableName.Organization, "maxSharedSecretLifetime");
const hasViewLimitColumn = await knex.schema.hasColumn(TableName.Organization, "maxSharedSecretViewLimit");
if (hasLifetimeColumn || hasViewLimitColumn) {
await knex.schema.alterTable(TableName.Organization, (t) => {
if (hasLifetimeColumn) {
t.dropColumn("maxSharedSecretLifetime");
}
if (hasViewLimitColumn) {
t.dropColumn("maxSharedSecretViewLimit");
}
});
}
}

View File

@ -0,0 +1,43 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (await knex.schema.hasTable(TableName.SecretSharing)) {
const hasEncryptedSalt = await knex.schema.hasColumn(TableName.SecretSharing, "encryptedSalt");
const hasAuthorizedEmails = await knex.schema.hasColumn(TableName.SecretSharing, "authorizedEmails");
if (!hasEncryptedSalt || !hasAuthorizedEmails) {
await knex.schema.alterTable(TableName.SecretSharing, (t) => {
// These two columns are only needed when secrets are shared with a specific list of emails
if (!hasEncryptedSalt) {
t.binary("encryptedSalt").nullable();
}
if (!hasAuthorizedEmails) {
t.json("authorizedEmails").nullable();
}
});
}
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasTable(TableName.SecretSharing)) {
const hasEncryptedSalt = await knex.schema.hasColumn(TableName.SecretSharing, "encryptedSalt");
const hasAuthorizedEmails = await knex.schema.hasColumn(TableName.SecretSharing, "authorizedEmails");
if (hasEncryptedSalt || hasAuthorizedEmails) {
await knex.schema.alterTable(TableName.SecretSharing, (t) => {
if (hasEncryptedSalt) {
t.dropColumn("encryptedSalt");
}
if (hasAuthorizedEmails) {
t.dropColumn("authorizedEmails");
}
});
}
}
}

View File

@ -0,0 +1,22 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
await knex.schema.alterTable(TableName.SecretSync, (t) => {
t.string("name", 64).notNullable().alter();
});
await knex.schema.alterTable(TableName.ProjectTemplates, (t) => {
t.string("name", 64).notNullable().alter();
});
await knex.schema.alterTable(TableName.AppConnection, (t) => {
t.string("name", 64).notNullable().alter();
});
await knex.schema.alterTable(TableName.SecretRotationV2, (t) => {
t.string("name", 64).notNullable().alter();
});
}
export async function down(): Promise<void> {
// No down migration or it will error
}

View File

@ -0,0 +1,205 @@
import slugify from "@sindresorhus/slugify";
import { Knex } from "knex";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
const hasCATable = await knex.schema.hasTable(TableName.CertificateAuthority);
const hasExternalCATable = await knex.schema.hasTable(TableName.ExternalCertificateAuthority);
const hasInternalCATable = await knex.schema.hasTable(TableName.InternalCertificateAuthority);
if (hasCATable && !hasInternalCATable) {
await knex.schema.createTableLike(TableName.InternalCertificateAuthority, TableName.CertificateAuthority, (t) => {
t.uuid("caId").nullable();
});
// @ts-expect-error intentional: migration
await knex(TableName.InternalCertificateAuthority).insert(knex(TableName.CertificateAuthority).select("*"));
await knex(TableName.InternalCertificateAuthority).update("caId", knex.ref("id"));
await knex.schema.alterTable(TableName.InternalCertificateAuthority, (t) => {
t.dropColumn("projectId");
t.dropColumn("requireTemplateForIssuance");
t.dropColumn("createdAt");
t.dropColumn("updatedAt");
t.dropColumn("status");
t.uuid("parentCaId")
.nullable()
.references("id")
.inTable(TableName.CertificateAuthority)
.onDelete("CASCADE")
.alter();
t.uuid("activeCaCertId").nullable().references("id").inTable(TableName.CertificateAuthorityCert).alter();
t.uuid("caId").notNullable().references("id").inTable(TableName.CertificateAuthority).onDelete("CASCADE").alter();
});
await knex.schema.alterTable(TableName.CertificateAuthority, (t) => {
t.renameColumn("requireTemplateForIssuance", "enableDirectIssuance");
t.string("name").nullable();
});
// prefill name for existing internal CAs and flip enableDirectIssuance
const cas = await knex(TableName.CertificateAuthority).select("id", "friendlyName", "enableDirectIssuance");
await Promise.all(
cas.map((ca) => {
const slugifiedName = ca.friendlyName
? slugify(`${ca.friendlyName.slice(0, 16)}-${alphaNumericNanoId(8)}`)
: slugify(alphaNumericNanoId(12));
return knex(TableName.CertificateAuthority)
.where({ id: ca.id })
.update({ name: slugifiedName, enableDirectIssuance: !ca.enableDirectIssuance });
})
);
await knex.schema.alterTable(TableName.CertificateAuthority, (t) => {
t.dropColumn("parentCaId");
t.dropColumn("type");
t.dropColumn("friendlyName");
t.dropColumn("organization");
t.dropColumn("ou");
t.dropColumn("country");
t.dropColumn("province");
t.dropColumn("locality");
t.dropColumn("commonName");
t.dropColumn("dn");
t.dropColumn("serialNumber");
t.dropColumn("maxPathLength");
t.dropColumn("keyAlgorithm");
t.dropColumn("notBefore");
t.dropColumn("notAfter");
t.dropColumn("activeCaCertId");
t.boolean("enableDirectIssuance").notNullable().defaultTo(true).alter();
t.string("name").notNullable().alter();
t.unique(["name", "projectId"]);
});
}
if (!hasExternalCATable) {
await knex.schema.createTable(TableName.ExternalCertificateAuthority, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.string("type").notNullable();
t.uuid("appConnectionId").nullable();
t.foreign("appConnectionId").references("id").inTable(TableName.AppConnection);
t.uuid("dnsAppConnectionId").nullable();
t.foreign("dnsAppConnectionId").references("id").inTable(TableName.AppConnection);
t.uuid("caId").notNullable().references("id").inTable(TableName.CertificateAuthority).onDelete("CASCADE");
t.binary("credentials");
t.json("configuration");
});
}
if (await knex.schema.hasTable(TableName.PkiSubscriber)) {
await knex.schema.alterTable(TableName.PkiSubscriber, (t) => {
t.string("ttl").nullable().alter();
t.boolean("enableAutoRenewal").notNullable().defaultTo(false);
t.integer("autoRenewalPeriodInDays");
t.datetime("lastAutoRenewAt");
t.string("lastOperationStatus");
t.text("lastOperationMessage");
t.dateTime("lastOperationAt");
});
}
}
export async function down(knex: Knex): Promise<void> {
const hasCATable = await knex.schema.hasTable(TableName.CertificateAuthority);
const hasExternalCATable = await knex.schema.hasTable(TableName.ExternalCertificateAuthority);
const hasInternalCATable = await knex.schema.hasTable(TableName.InternalCertificateAuthority);
if (hasCATable && hasInternalCATable) {
// First add all columns as nullable
await knex.schema.alterTable(TableName.CertificateAuthority, (t) => {
t.uuid("parentCaId").nullable().references("id").inTable(TableName.CertificateAuthority).onDelete("CASCADE");
t.string("type").nullable();
t.string("friendlyName").nullable();
t.string("organization").nullable();
t.string("ou").nullable();
t.string("country").nullable();
t.string("province").nullable();
t.string("locality").nullable();
t.string("commonName").nullable();
t.string("dn").nullable();
t.string("serialNumber").nullable().unique();
t.integer("maxPathLength").nullable();
t.string("keyAlgorithm").nullable();
t.timestamp("notBefore").nullable();
t.timestamp("notAfter").nullable();
t.uuid("activeCaCertId").nullable().references("id").inTable(TableName.CertificateAuthorityCert);
t.renameColumn("enableDirectIssuance", "requireTemplateForIssuance");
t.dropColumn("name");
});
// flip requireTemplateForIssuance for existing internal CAs
const cas = await knex(TableName.CertificateAuthority).select("id", "requireTemplateForIssuance");
await Promise.all(
cas.map((ca) => {
return (
knex(TableName.CertificateAuthority)
.where({ id: ca.id })
// @ts-expect-error intentional: migration
.update({ requireTemplateForIssuance: !ca.requireTemplateForIssuance })
);
})
);
await knex.raw(`
UPDATE ${TableName.CertificateAuthority} ca
SET
type = ica.type,
"friendlyName" = ica."friendlyName",
organization = ica.organization,
ou = ica.ou,
country = ica.country,
province = ica.province,
locality = ica.locality,
"commonName" = ica."commonName",
dn = ica.dn,
"parentCaId" = ica."parentCaId",
"serialNumber" = ica."serialNumber",
"maxPathLength" = ica."maxPathLength",
"keyAlgorithm" = ica."keyAlgorithm",
"notBefore" = ica."notBefore",
"notAfter" = ica."notAfter",
"activeCaCertId" = ica."activeCaCertId"
FROM ${TableName.InternalCertificateAuthority} ica
WHERE ca.id = ica."caId"
`);
await knex.schema.alterTable(TableName.CertificateAuthority, (t) => {
t.string("type").notNullable().alter();
t.string("friendlyName").notNullable().alter();
t.string("organization").notNullable().alter();
t.string("ou").notNullable().alter();
t.string("country").notNullable().alter();
t.string("province").notNullable().alter();
t.string("locality").notNullable().alter();
t.string("commonName").notNullable().alter();
t.string("dn").notNullable().alter();
t.string("keyAlgorithm").notNullable().alter();
t.boolean("requireTemplateForIssuance").notNullable().defaultTo(false).alter();
});
await knex.schema.dropTable(TableName.InternalCertificateAuthority);
}
if (hasExternalCATable) {
await knex.schema.dropTable(TableName.ExternalCertificateAuthority);
}
if (await knex.schema.hasTable(TableName.PkiSubscriber)) {
await knex.schema.alterTable(TableName.PkiSubscriber, (t) => {
t.dropColumn("enableAutoRenewal");
t.dropColumn("autoRenewalPeriodInDays");
t.dropColumn("lastAutoRenewAt");
t.dropColumn("lastOperationStatus");
t.dropColumn("lastOperationMessage");
t.dropColumn("lastOperationAt");
});
}
}

View File

@ -0,0 +1,139 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasColumn(TableName.IdentityAccessToken, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityAccessToken, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityUniversalAuth, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityUniversalAuth, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityAwsAuth, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityAwsAuth, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityOidcAuth, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityOidcAuth, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityAzureAuth, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityAzureAuth, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityGcpAuth, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityGcpAuth, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityJwtAuth, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityJwtAuth, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityKubernetesAuth, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityKubernetesAuth, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityLdapAuth, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityLdapAuth, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityOciAuth, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityOciAuth, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
if (!(await knex.schema.hasColumn(TableName.IdentityTokenAuth, "accessTokenPeriod"))) {
await knex.schema.alterTable(TableName.IdentityTokenAuth, (t) => {
t.bigInteger("accessTokenPeriod").defaultTo(0).notNullable();
});
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasColumn(TableName.IdentityAccessToken, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityAccessToken, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
if (await knex.schema.hasColumn(TableName.IdentityUniversalAuth, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityUniversalAuth, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
if (await knex.schema.hasColumn(TableName.IdentityAwsAuth, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityAwsAuth, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
if (await knex.schema.hasColumn(TableName.IdentityOidcAuth, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityOidcAuth, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
if (await knex.schema.hasColumn(TableName.IdentityAzureAuth, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityAzureAuth, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
if (await knex.schema.hasColumn(TableName.IdentityGcpAuth, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityGcpAuth, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
if (await knex.schema.hasColumn(TableName.IdentityJwtAuth, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityJwtAuth, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
if (await knex.schema.hasColumn(TableName.IdentityKubernetesAuth, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityKubernetesAuth, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
if (await knex.schema.hasColumn(TableName.IdentityLdapAuth, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityLdapAuth, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
if (await knex.schema.hasColumn(TableName.IdentityOciAuth, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityOciAuth, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
if (await knex.schema.hasColumn(TableName.IdentityTokenAuth, "accessTokenPeriod")) {
await knex.schema.alterTable(TableName.IdentityTokenAuth, (t) => {
t.dropColumn("accessTokenPeriod");
});
}
}

View File

@ -0,0 +1,27 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> {
if (await knex.schema.hasTable(TableName.SecretSharing)) {
const hasEncryptedSalt = await knex.schema.hasColumn(TableName.SecretSharing, "encryptedSalt");
if (hasEncryptedSalt) {
await knex.schema.alterTable(TableName.SecretSharing, (t) => {
t.dropColumn("encryptedSalt");
});
}
}
}
export async function down(knex: Knex): Promise<void> {
if (await knex.schema.hasTable(TableName.SecretSharing)) {
const hasEncryptedSalt = await knex.schema.hasColumn(TableName.SecretSharing, "encryptedSalt");
if (!hasEncryptedSalt) {
await knex.schema.alterTable(TableName.SecretSharing, (t) => {
t.binary("encryptedSalt").nullable();
});
}
}
}

View File

@ -11,25 +11,10 @@ export const CertificateAuthoritiesSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
parentCaId: z.string().uuid().nullable().optional(),
projectId: z.string(),
type: z.string(),
enableDirectIssuance: z.boolean().default(true),
status: z.string(),
friendlyName: z.string(),
organization: z.string(),
ou: z.string(),
country: z.string(),
province: z.string(),
locality: z.string(),
commonName: z.string(),
dn: z.string(),
serialNumber: z.string().nullable().optional(),
maxPathLength: z.number().nullable().optional(),
keyAlgorithm: z.string(),
notBefore: z.date().nullable().optional(),
notAfter: z.date().nullable().optional(),
activeCaCertId: z.string().uuid().nullable().optional(),
requireTemplateForIssuance: z.boolean().default(false)
name: z.string()
});
export type TCertificateAuthorities = z.infer<typeof CertificateAuthoritiesSchema>;

View File

@ -14,7 +14,8 @@ export const CertificateBodiesSchema = z.object({
createdAt: z.date(),
updatedAt: z.date(),
certId: z.string().uuid(),
encryptedCertificate: zodBuffer
encryptedCertificate: zodBuffer,
encryptedCertificateChain: zodBuffer.nullable().optional()
});
export type TCertificateBodies = z.infer<typeof CertificateBodiesSchema>;

View File

@ -5,6 +5,8 @@
import { z } from "zod";
import { zodBuffer } from "@app/lib/zod";
import { TImmutableDBKeys } from "./models";
export const CertificateSecretsSchema = z.object({
@ -12,8 +14,7 @@ export const CertificateSecretsSchema = z.object({
createdAt: z.date(),
updatedAt: z.date(),
certId: z.string().uuid(),
pk: z.string(),
sk: z.string()
encryptedPrivateKey: zodBuffer
});
export type TCertificateSecrets = z.infer<typeof CertificateSecretsSchema>;

View File

@ -11,7 +11,7 @@ export const CertificatesSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
caId: z.string().uuid(),
caId: z.string().uuid().nullable().optional(),
status: z.string(),
serialNumber: z.string(),
friendlyName: z.string(),
@ -20,11 +20,13 @@ export const CertificatesSchema = z.object({
notAfter: z.date(),
revokedAt: z.date().nullable().optional(),
revocationReason: z.number().nullable().optional(),
altNames: z.string().default("").nullable().optional(),
caCertId: z.string().uuid(),
altNames: z.string().nullable().optional(),
caCertId: z.string().uuid().nullable().optional(),
certificateTemplateId: z.string().uuid().nullable().optional(),
keyUsages: z.string().array().nullable().optional(),
extendedKeyUsages: z.string().array().nullable().optional()
extendedKeyUsages: z.string().array().nullable().optional(),
pkiSubscriberId: z.string().uuid().nullable().optional(),
projectId: z.string()
});
export type TCertificates = z.infer<typeof CertificatesSchema>;

View File

@ -27,7 +27,8 @@ export const DynamicSecretsSchema = z.object({
createdAt: z.date(),
updatedAt: z.date(),
encryptedInput: zodBuffer,
projectGatewayId: z.string().uuid().nullable().optional()
projectGatewayId: z.string().uuid().nullable().optional(),
gatewayId: z.string().uuid().nullable().optional()
});
export type TDynamicSecrets = z.infer<typeof DynamicSecretsSchema>;

View File

@ -0,0 +1,29 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { zodBuffer } from "@app/lib/zod";
import { TImmutableDBKeys } from "./models";
export const ExternalCertificateAuthoritiesSchema = z.object({
id: z.string().uuid(),
type: z.string(),
appConnectionId: z.string().uuid().nullable().optional(),
dnsAppConnectionId: z.string().uuid().nullable().optional(),
caId: z.string().uuid(),
credentials: zodBuffer.nullable().optional(),
configuration: z.unknown().nullable().optional()
});
export type TExternalCertificateAuthorities = z.infer<typeof ExternalCertificateAuthoritiesSchema>;
export type TExternalCertificateAuthoritiesInsert = Omit<
z.input<typeof ExternalCertificateAuthoritiesSchema>,
TImmutableDBKeys
>;
export type TExternalCertificateAuthoritiesUpdate = Partial<
Omit<z.input<typeof ExternalCertificateAuthoritiesSchema>, TImmutableDBKeys>
>;

View File

@ -0,0 +1,24 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { zodBuffer } from "@app/lib/zod";
import { TImmutableDBKeys } from "./models";
export const GithubOrgSyncConfigsSchema = z.object({
id: z.string().uuid(),
githubOrgName: z.string(),
isActive: z.boolean().default(false).nullable().optional(),
encryptedGithubOrgAccessToken: zodBuffer.nullable().optional(),
orgId: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TGithubOrgSyncConfigs = z.infer<typeof GithubOrgSyncConfigsSchema>;
export type TGithubOrgSyncConfigsInsert = Omit<z.input<typeof GithubOrgSyncConfigsSchema>, TImmutableDBKeys>;
export type TGithubOrgSyncConfigsUpdate = Partial<Omit<z.input<typeof GithubOrgSyncConfigsSchema>, TImmutableDBKeys>>;

View File

@ -21,7 +21,8 @@ export const IdentityAccessTokensSchema = z.object({
createdAt: z.date(),
updatedAt: z.date(),
name: z.string().nullable().optional(),
authMethod: z.string()
authMethod: z.string(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityAccessTokens = z.infer<typeof IdentityAccessTokensSchema>;

View File

@ -19,7 +19,8 @@ export const IdentityAwsAuthsSchema = z.object({
type: z.string(),
stsEndpoint: z.string(),
allowedPrincipalArns: z.string(),
allowedAccountIds: z.string()
allowedAccountIds: z.string(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityAwsAuths = z.infer<typeof IdentityAwsAuthsSchema>;

View File

@ -18,7 +18,8 @@ export const IdentityAzureAuthsSchema = z.object({
identityId: z.string().uuid(),
tenantId: z.string(),
resource: z.string(),
allowedServicePrincipalIds: z.string()
allowedServicePrincipalIds: z.string(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityAzureAuths = z.infer<typeof IdentityAzureAuthsSchema>;

View File

@ -19,7 +19,8 @@ export const IdentityGcpAuthsSchema = z.object({
type: z.string(),
allowedServiceAccounts: z.string().nullable().optional(),
allowedProjects: z.string().nullable().optional(),
allowedZones: z.string().nullable().optional()
allowedZones: z.string().nullable().optional(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityGcpAuths = z.infer<typeof IdentityGcpAuthsSchema>;

View File

@ -25,7 +25,8 @@ export const IdentityJwtAuthsSchema = z.object({
boundClaims: z.unknown(),
boundSubject: z.string(),
createdAt: z.date(),
updatedAt: z.date()
updatedAt: z.date(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityJwtAuths = z.infer<typeof IdentityJwtAuthsSchema>;

View File

@ -29,7 +29,9 @@ export const IdentityKubernetesAuthsSchema = z.object({
allowedNames: z.string(),
allowedAudience: z.string(),
encryptedKubernetesTokenReviewerJwt: zodBuffer.nullable().optional(),
encryptedKubernetesCaCertificate: zodBuffer.nullable().optional()
encryptedKubernetesCaCertificate: zodBuffer.nullable().optional(),
gatewayId: z.string().uuid().nullable().optional(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityKubernetesAuths = z.infer<typeof IdentityKubernetesAuthsSchema>;

View File

@ -0,0 +1,33 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { zodBuffer } from "@app/lib/zod";
import { TImmutableDBKeys } from "./models";
export const IdentityLdapAuthsSchema = z.object({
id: z.string().uuid(),
accessTokenTTL: z.coerce.number().default(7200),
accessTokenMaxTTL: z.coerce.number().default(7200),
accessTokenNumUsesLimit: z.coerce.number().default(0),
accessTokenTrustedIps: z.unknown(),
identityId: z.string().uuid(),
encryptedBindDN: zodBuffer,
encryptedBindPass: zodBuffer,
encryptedLdapCaCertificate: zodBuffer.nullable().optional(),
url: z.string(),
searchBase: z.string(),
searchFilter: z.string(),
allowedFields: z.unknown().nullable().optional(),
createdAt: z.date(),
updatedAt: z.date(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityLdapAuths = z.infer<typeof IdentityLdapAuthsSchema>;
export type TIdentityLdapAuthsInsert = Omit<z.input<typeof IdentityLdapAuthsSchema>, TImmutableDBKeys>;
export type TIdentityLdapAuthsUpdate = Partial<Omit<z.input<typeof IdentityLdapAuthsSchema>, TImmutableDBKeys>>;

View File

@ -0,0 +1,27 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const IdentityOciAuthsSchema = z.object({
id: z.string().uuid(),
accessTokenTTL: z.coerce.number().default(7200),
accessTokenMaxTTL: z.coerce.number().default(7200),
accessTokenNumUsesLimit: z.coerce.number().default(0),
accessTokenTrustedIps: z.unknown(),
createdAt: z.date(),
updatedAt: z.date(),
identityId: z.string().uuid(),
type: z.string(),
tenancyOcid: z.string(),
allowedUsernames: z.string().nullable().optional(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityOciAuths = z.infer<typeof IdentityOciAuthsSchema>;
export type TIdentityOciAuthsInsert = Omit<z.input<typeof IdentityOciAuthsSchema>, TImmutableDBKeys>;
export type TIdentityOciAuthsUpdate = Partial<Omit<z.input<typeof IdentityOciAuthsSchema>, TImmutableDBKeys>>;

View File

@ -27,7 +27,8 @@ export const IdentityOidcAuthsSchema = z.object({
createdAt: z.date(),
updatedAt: z.date(),
encryptedCaCertificate: zodBuffer.nullable().optional(),
claimMetadataMapping: z.unknown().nullable().optional()
claimMetadataMapping: z.unknown().nullable().optional(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityOidcAuths = z.infer<typeof IdentityOidcAuthsSchema>;

View File

@ -15,7 +15,8 @@ export const IdentityTokenAuthsSchema = z.object({
accessTokenTrustedIps: z.unknown(),
createdAt: z.date(),
updatedAt: z.date(),
identityId: z.string().uuid()
identityId: z.string().uuid(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityTokenAuths = z.infer<typeof IdentityTokenAuthsSchema>;

View File

@ -17,7 +17,8 @@ export const IdentityUniversalAuthsSchema = z.object({
accessTokenTrustedIps: z.unknown(),
createdAt: z.date(),
updatedAt: z.date(),
identityId: z.string().uuid()
identityId: z.string().uuid(),
accessTokenPeriod: z.coerce.number().default(0)
});
export type TIdentityUniversalAuths = z.infer<typeof IdentityUniversalAuthsSchema>;

View File

@ -20,11 +20,13 @@ export * from "./certificate-templates";
export * from "./certificates";
export * from "./dynamic-secret-leases";
export * from "./dynamic-secrets";
export * from "./external-certificate-authorities";
export * from "./external-group-org-role-mappings";
export * from "./external-kms";
export * from "./gateways";
export * from "./git-app-install-sessions";
export * from "./git-app-org";
export * from "./github-org-sync-configs";
export * from "./group-project-membership-roles";
export * from "./group-project-memberships";
export * from "./groups";
@ -36,6 +38,7 @@ export * from "./identity-gcp-auths";
export * from "./identity-jwt-auths";
export * from "./identity-kubernetes-auths";
export * from "./identity-metadata";
export * from "./identity-oci-auths";
export * from "./identity-oidc-auths";
export * from "./identity-org-memberships";
export * from "./identity-project-additional-privilege";
@ -47,6 +50,7 @@ export * from "./identity-universal-auths";
export * from "./incident-contacts";
export * from "./integration-auths";
export * from "./integrations";
export * from "./internal-certificate-authorities";
export * from "./internal-kms";
export * from "./kmip-client-certificates";
export * from "./kmip-clients";
@ -57,6 +61,7 @@ export * from "./kms-keys";
export * from "./kms-root-config";
export * from "./ldap-configs";
export * from "./ldap-group-maps";
export * from "./microsoft-teams-integrations";
export * from "./models";
export * from "./oidc-configs";
export * from "./org-bots";
@ -67,6 +72,7 @@ export * from "./organizations";
export * from "./pki-alerts";
export * from "./pki-collection-items";
export * from "./pki-collections";
export * from "./pki-subscribers";
export * from "./project-bots";
export * from "./project-environments";
export * from "./project-gateways";
@ -126,6 +132,8 @@ export * from "./ssh-certificate-authority-secrets";
export * from "./ssh-certificate-bodies";
export * from "./ssh-certificate-templates";
export * from "./ssh-certificates";
export * from "./ssh-host-group-memberships";
export * from "./ssh-host-groups";
export * from "./ssh-host-login-user-mappings";
export * from "./ssh-host-login-users";
export * from "./ssh-hosts";

View File

@ -0,0 +1,38 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const InternalCertificateAuthoritiesSchema = z.object({
id: z.string().uuid(),
parentCaId: z.string().uuid().nullable().optional(),
type: z.string(),
friendlyName: z.string(),
organization: z.string(),
ou: z.string(),
country: z.string(),
province: z.string(),
locality: z.string(),
commonName: z.string(),
dn: z.string(),
serialNumber: z.string().nullable().optional(),
maxPathLength: z.number().nullable().optional(),
keyAlgorithm: z.string(),
notBefore: z.date().nullable().optional(),
notAfter: z.date().nullable().optional(),
activeCaCertId: z.string().uuid().nullable().optional(),
caId: z.string().uuid()
});
export type TInternalCertificateAuthorities = z.infer<typeof InternalCertificateAuthoritiesSchema>;
export type TInternalCertificateAuthoritiesInsert = Omit<
z.input<typeof InternalCertificateAuthoritiesSchema>,
TImmutableDBKeys
>;
export type TInternalCertificateAuthoritiesUpdate = Partial<
Omit<z.input<typeof InternalCertificateAuthoritiesSchema>, TImmutableDBKeys>
>;

View File

@ -13,7 +13,7 @@ export const KmipOrgServerCertificatesSchema = z.object({
id: z.string().uuid(),
orgId: z.string().uuid(),
commonName: z.string(),
altNames: z.string(),
altNames: z.string().nullable().optional(),
serialNumber: z.string(),
keyAlgorithm: z.string(),
issuedAt: z.date(),

View File

@ -0,0 +1,31 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { zodBuffer } from "@app/lib/zod";
import { TImmutableDBKeys } from "./models";
export const MicrosoftTeamsIntegrationsSchema = z.object({
id: z.string().uuid(),
internalTeamsAppId: z.string().nullable().optional(),
tenantId: z.string(),
encryptedAccessToken: zodBuffer.nullable().optional(),
encryptedBotAccessToken: zodBuffer.nullable().optional(),
accessTokenExpiresAt: z.date().nullable().optional(),
botAccessTokenExpiresAt: z.date().nullable().optional(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TMicrosoftTeamsIntegrations = z.infer<typeof MicrosoftTeamsIntegrationsSchema>;
export type TMicrosoftTeamsIntegrationsInsert = Omit<
z.input<typeof MicrosoftTeamsIntegrationsSchema>,
TImmutableDBKeys
>;
export type TMicrosoftTeamsIntegrationsUpdate = Partial<
Omit<z.input<typeof MicrosoftTeamsIntegrationsSchema>, TImmutableDBKeys>
>;

View File

@ -2,6 +2,8 @@ import { z } from "zod";
export enum TableName {
Users = "users",
SshHostGroup = "ssh_host_groups",
SshHostGroupMembership = "ssh_host_group_memberships",
SshHost = "ssh_hosts",
SshHostLoginUser = "ssh_host_login_users",
SshHostLoginUserMapping = "ssh_host_login_user_mappings",
@ -11,6 +13,8 @@ export enum TableName {
SshCertificate = "ssh_certificates",
SshCertificateBody = "ssh_certificate_bodies",
CertificateAuthority = "certificate_authorities",
ExternalCertificateAuthority = "external_certificate_authorities",
InternalCertificateAuthority = "internal_certificate_authorities",
CertificateTemplateEstConfig = "certificate_template_est_configs",
CertificateAuthorityCert = "certificate_authority_certs",
CertificateAuthoritySecret = "certificate_authority_secret",
@ -19,6 +23,7 @@ export enum TableName {
CertificateBody = "certificate_bodies",
CertificateSecret = "certificate_secrets",
CertificateTemplate = "certificate_templates",
PkiSubscriber = "pki_subscribers",
PkiAlert = "pki_alerts",
PkiCollection = "pki_collections",
PkiCollectionItem = "pki_collection_items",
@ -76,8 +81,10 @@ export enum TableName {
IdentityAzureAuth = "identity_azure_auths",
IdentityUaClientSecret = "identity_ua_client_secrets",
IdentityAwsAuth = "identity_aws_auths",
IdentityOciAuth = "identity_oci_auths",
IdentityOidcAuth = "identity_oidc_auths",
IdentityJwtAuth = "identity_jwt_auths",
IdentityLdapAuth = "identity_ldap_auths",
IdentityOrgMembership = "identity_org_memberships",
IdentityProjectMembership = "identity_project_memberships",
IdentityProjectMembershipRole = "identity_project_membership_role",
@ -146,7 +153,11 @@ export enum TableName {
KmipOrgServerCertificates = "kmip_org_server_certificates",
KmipClientCertificates = "kmip_client_certificates",
SecretRotationV2 = "secret_rotations_v2",
SecretRotationV2SecretMapping = "secret_rotation_v2_secret_mappings"
SecretRotationV2SecretMapping = "secret_rotation_v2_secret_mappings",
MicrosoftTeamsIntegrations = "microsoft_teams_integrations",
ProjectMicrosoftTeamsConfigs = "project_microsoft_teams_configs",
SecretReminderRecipients = "secret_reminder_recipients",
GithubOrgSyncConfig = "github_org_sync_configs"
}
export type TImmutableDBKeys = "id" | "createdAt" | "updatedAt";
@ -179,11 +190,16 @@ export enum OrgMembershipStatus {
}
export enum ProjectMembershipRole {
// general
Admin = "admin",
Member = "member",
Custom = "custom",
Viewer = "viewer",
NoAccess = "no-access"
NoAccess = "no-access",
// ssh
SshHostBootstrapper = "ssh-host-bootstrapper",
// kms
KmsCryptographicOperator = "cryptographic-operator"
}
export enum SecretEncryptionAlgo {
@ -220,8 +236,10 @@ export enum IdentityAuthMethod {
GCP_AUTH = "gcp-auth",
AWS_AUTH = "aws-auth",
AZURE_AUTH = "azure-auth",
OCI_AUTH = "oci-auth",
OIDC_AUTH = "oidc-auth",
JWT_AUTH = "jwt-auth"
JWT_AUTH = "jwt-auth",
LDAP_AUTH = "ldap-auth"
}
export enum ProjectType {

View File

@ -30,9 +30,9 @@ export const OidcConfigsSchema = z.object({
updatedAt: z.date(),
orgId: z.string().uuid(),
lastUsed: z.date().nullable().optional(),
manageGroupMemberships: z.boolean().default(false),
encryptedOidcClientId: zodBuffer,
encryptedOidcClientSecret: zodBuffer,
manageGroupMemberships: z.boolean().default(false),
jwtSignatureAlgorithm: z.string().default("RS256")
});

View File

@ -27,7 +27,16 @@ export const OrganizationsSchema = z.object({
shouldUseNewPrivilegeSystem: z.boolean().default(true),
privilegeUpgradeInitiatedByUsername: z.string().nullable().optional(),
privilegeUpgradeInitiatedAt: z.date().nullable().optional(),
bypassOrgAuthEnabled: z.boolean().default(false)
bypassOrgAuthEnabled: z.boolean().default(false),
userTokenExpiration: z.string().nullable().optional(),
secretsProductEnabled: z.boolean().default(true).nullable().optional(),
pkiProductEnabled: z.boolean().default(true).nullable().optional(),
kmsProductEnabled: z.boolean().default(true).nullable().optional(),
sshProductEnabled: z.boolean().default(true).nullable().optional(),
scannerProductEnabled: z.boolean().default(true).nullable().optional(),
shareSecretsProductEnabled: z.boolean().default(true).nullable().optional(),
maxSharedSecretLifetime: z.number().default(2592000).nullable().optional(),
maxSharedSecretViewLimit: z.number().nullable().optional()
});
export type TOrganizations = z.infer<typeof OrganizationsSchema>;

View File

@ -0,0 +1,33 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const PkiSubscribersSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
projectId: z.string(),
caId: z.string().uuid().nullable().optional(),
name: z.string(),
commonName: z.string(),
subjectAlternativeNames: z.string().array(),
ttl: z.string().nullable().optional(),
keyUsages: z.string().array(),
extendedKeyUsages: z.string().array(),
status: z.string(),
enableAutoRenewal: z.boolean().default(false),
autoRenewalPeriodInDays: z.number().nullable().optional(),
lastAutoRenewAt: z.date().nullable().optional(),
lastOperationStatus: z.string().nullable().optional(),
lastOperationMessage: z.string().nullable().optional(),
lastOperationAt: z.date().nullable().optional()
});
export type TPkiSubscribers = z.infer<typeof PkiSubscribersSchema>;
export type TPkiSubscribersInsert = Omit<z.input<typeof PkiSubscribersSchema>, TImmutableDBKeys>;
export type TPkiSubscribersUpdate = Partial<Omit<z.input<typeof PkiSubscribersSchema>, TImmutableDBKeys>>;

View File

@ -0,0 +1,29 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const ProjectMicrosoftTeamsConfigsSchema = z.object({
id: z.string().uuid(),
projectId: z.string(),
microsoftTeamsIntegrationId: z.string().uuid(),
isAccessRequestNotificationEnabled: z.boolean().default(false),
isSecretRequestNotificationEnabled: z.boolean().default(false),
accessRequestChannels: z.unknown(),
secretRequestChannels: z.unknown(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TProjectMicrosoftTeamsConfigs = z.infer<typeof ProjectMicrosoftTeamsConfigsSchema>;
export type TProjectMicrosoftTeamsConfigsInsert = Omit<
z.input<typeof ProjectMicrosoftTeamsConfigsSchema>,
TImmutableDBKeys
>;
export type TProjectMicrosoftTeamsConfigsUpdate = Partial<
Omit<z.input<typeof ProjectMicrosoftTeamsConfigsSchema>, TImmutableDBKeys>
>;

View File

@ -12,10 +12,11 @@ export const ProjectTemplatesSchema = z.object({
name: z.string(),
description: z.string().nullable().optional(),
roles: z.unknown(),
environments: z.unknown(),
environments: z.unknown().nullable().optional(),
orgId: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date()
updatedAt: z.date(),
type: z.string().default("secret-manager")
});
export type TProjectTemplates = z.infer<typeof ProjectTemplatesSchema>;

View File

@ -27,7 +27,8 @@ export const ProjectsSchema = z.object({
description: z.string().nullable().optional(),
type: z.string(),
enforceCapitalization: z.boolean().default(false),
hasDeleteProtection: z.boolean().default(true).nullable().optional()
hasDeleteProtection: z.boolean().default(false).nullable().optional(),
secretSharing: z.boolean().default(true)
});
export type TProjects = z.infer<typeof ProjectsSchema>;

View File

@ -0,0 +1,23 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const SecretReminderRecipientsSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
secretId: z.string().uuid(),
userId: z.string().uuid(),
projectId: z.string()
});
export type TSecretReminderRecipients = z.infer<typeof SecretReminderRecipientsSchema>;
export type TSecretReminderRecipientsInsert = Omit<z.input<typeof SecretReminderRecipientsSchema>, TImmutableDBKeys>;
export type TSecretReminderRecipientsUpdate = Partial<
Omit<z.input<typeof SecretReminderRecipientsSchema>, TImmutableDBKeys>
>;

View File

@ -27,7 +27,8 @@ export const SecretSharingSchema = z.object({
password: z.string().nullable().optional(),
encryptedSecret: zodBuffer.nullable().optional(),
identifier: z.string().nullable().optional(),
type: z.string().default("share")
type: z.string().default("share"),
authorizedEmails: z.unknown().nullable().optional()
});
export type TSecretSharing = z.infer<typeof SecretSharingSchema>;

View File

@ -0,0 +1,22 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const SshHostGroupMembershipsSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
sshHostGroupId: z.string().uuid(),
sshHostId: z.string().uuid()
});
export type TSshHostGroupMemberships = z.infer<typeof SshHostGroupMembershipsSchema>;
export type TSshHostGroupMembershipsInsert = Omit<z.input<typeof SshHostGroupMembershipsSchema>, TImmutableDBKeys>;
export type TSshHostGroupMembershipsUpdate = Partial<
Omit<z.input<typeof SshHostGroupMembershipsSchema>, TImmutableDBKeys>
>;

View File

@ -0,0 +1,20 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const SshHostGroupsSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
projectId: z.string(),
name: z.string()
});
export type TSshHostGroups = z.infer<typeof SshHostGroupsSchema>;
export type TSshHostGroupsInsert = Omit<z.input<typeof SshHostGroupsSchema>, TImmutableDBKeys>;
export type TSshHostGroupsUpdate = Partial<Omit<z.input<typeof SshHostGroupsSchema>, TImmutableDBKeys>>;

View File

@ -12,7 +12,8 @@ export const SshHostLoginUserMappingsSchema = z.object({
createdAt: z.date(),
updatedAt: z.date(),
sshHostLoginUserId: z.string().uuid(),
userId: z.string().uuid().nullable().optional()
userId: z.string().uuid().nullable().optional(),
groupId: z.string().uuid().nullable().optional()
});
export type TSshHostLoginUserMappings = z.infer<typeof SshHostLoginUserMappingsSchema>;

View File

@ -11,8 +11,9 @@ export const SshHostLoginUsersSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
sshHostId: z.string().uuid(),
loginUser: z.string()
sshHostId: z.string().uuid().nullable().optional(),
loginUser: z.string(),
sshHostGroupId: z.string().uuid().nullable().optional()
});
export type TSshHostLoginUsers = z.infer<typeof SshHostLoginUsersSchema>;

View File

@ -16,7 +16,8 @@ export const SshHostsSchema = z.object({
userCertTtl: z.string(),
hostCertTtl: z.string(),
userSshCaId: z.string().uuid(),
hostSshCaId: z.string().uuid()
hostSshCaId: z.string().uuid(),
alias: z.string().nullable().optional()
});
export type TSshHosts = z.infer<typeof SshHostsSchema>;

View File

@ -26,7 +26,10 @@ export const SuperAdminSchema = z.object({
encryptedSlackClientSecret: zodBuffer.nullable().optional(),
authConsentContent: z.string().nullable().optional(),
pageFrameContent: z.string().nullable().optional(),
adminIdentityIds: z.string().array().nullable().optional()
adminIdentityIds: z.string().array().nullable().optional(),
encryptedMicrosoftTeamsAppId: zodBuffer.nullable().optional(),
encryptedMicrosoftTeamsClientSecret: zodBuffer.nullable().optional(),
encryptedMicrosoftTeamsBotId: zodBuffer.nullable().optional()
});
export type TSuperAdmin = z.infer<typeof SuperAdminSchema>;

View File

@ -14,7 +14,8 @@ export const WorkflowIntegrationsSchema = z.object({
orgId: z.string().uuid(),
description: z.string().nullable().optional(),
createdAt: z.date(),
updatedAt: z.date()
updatedAt: z.date(),
status: z.string().default("installed")
});
export type TWorkflowIntegrations = z.infer<typeof WorkflowIntegrationsSchema>;

View File

@ -2,6 +2,7 @@ import { z } from "zod";
import { AccessApprovalRequestsReviewersSchema, AccessApprovalRequestsSchema, UsersSchema } from "@app/db/schemas";
import { ApprovalStatus } from "@app/ee/services/access-approval-request/access-approval-request-types";
import { writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@ -18,6 +19,9 @@ export const registerAccessApprovalRequestRouter = async (server: FastifyZodProv
server.route({
url: "/",
method: "POST",
config: {
rateLimit: writeLimit
},
schema: {
body: z.object({
permissions: z.any().array(),
@ -150,7 +154,8 @@ export const registerAccessApprovalRequestRouter = async (server: FastifyZodProv
requestId: z.string().trim()
}),
body: z.object({
status: z.enum([ApprovalStatus.APPROVED, ApprovalStatus.REJECTED])
status: z.enum([ApprovalStatus.APPROVED, ApprovalStatus.REJECTED]),
bypassReason: z.string().min(10).max(1000).optional()
}),
response: {
200: z.object({
@ -166,7 +171,8 @@ export const registerAccessApprovalRequestRouter = async (server: FastifyZodProv
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
requestId: req.params.requestId,
status: req.body.status
status: req.body.status,
bypassReason: req.body.bypassReason
});
return { review };

View File

@ -0,0 +1,123 @@
import z from "zod";
import {
CreateOCIConnectionSchema,
SanitizedOCIConnectionSchema,
UpdateOCIConnectionSchema
} from "@app/ee/services/app-connections/oci";
import { readLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { AuthMode } from "@app/services/auth/auth-type";
import { registerAppConnectionEndpoints } from "../../../../server/routes/v1/app-connection-routers/app-connection-endpoints";
export const registerOCIConnectionRouter = async (server: FastifyZodProvider) => {
registerAppConnectionEndpoints({
app: AppConnection.OCI,
server,
sanitizedResponseSchema: SanitizedOCIConnectionSchema,
createSchema: CreateOCIConnectionSchema,
updateSchema: UpdateOCIConnectionSchema
});
// The following endpoints are for internal Infisical App use only and not part of the public API
server.route({
method: "GET",
url: `/:connectionId/compartments`,
config: {
rateLimit: readLimit
},
schema: {
params: z.object({
connectionId: z.string().uuid()
}),
response: {
200: z
.object({
id: z.string(),
name: z.string()
})
.array()
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { connectionId } = req.params;
const compartments = await server.services.appConnection.oci.listCompartments(connectionId, req.permission);
return compartments;
}
});
server.route({
method: "GET",
url: `/:connectionId/vaults`,
config: {
rateLimit: readLimit
},
schema: {
params: z.object({
connectionId: z.string().uuid()
}),
querystring: z.object({
compartmentOcid: z.string().min(1, "Compartment OCID required")
}),
response: {
200: z
.object({
id: z.string(),
displayName: z.string()
})
.array()
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { connectionId } = req.params;
const { compartmentOcid } = req.query;
const vaults = await server.services.appConnection.oci.listVaults(
{ connectionId, compartmentOcid },
req.permission
);
return vaults;
}
});
server.route({
method: "GET",
url: `/:connectionId/vault-keys`,
config: {
rateLimit: readLimit
},
schema: {
params: z.object({
connectionId: z.string().uuid()
}),
querystring: z.object({
compartmentOcid: z.string().min(1, "Compartment OCID required"),
vaultOcid: z.string().min(1, "Vault OCID required")
}),
response: {
200: z
.object({
id: z.string(),
displayName: z.string()
})
.array()
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { connectionId } = req.params;
const { compartmentOcid, vaultOcid } = req.query;
const keys = await server.services.appConnection.oci.listVaultKeys(
{ connectionId, compartmentOcid, vaultOcid },
req.permission
);
return keys;
}
});
};

View File

@ -0,0 +1,124 @@
import { requestContext } from "@fastify/request-context";
import { z } from "zod";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
import { writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
export const registerAssumePrivilegeRouter = async (server: FastifyZodProvider) => {
server.route({
method: "POST",
url: "/:projectId/assume-privileges",
config: {
rateLimit: writeLimit
},
schema: {
params: z.object({
projectId: z.string()
}),
body: z.object({
actorType: z.enum([ActorType.USER, ActorType.IDENTITY]),
actorId: z.string()
}),
response: {
200: z.object({
message: z.string()
})
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req, res) => {
if (req.auth.authMode === AuthMode.JWT) {
const payload = await server.services.assumePrivileges.assumeProjectPrivileges({
targetActorType: req.body.actorType,
targetActorId: req.body.actorId,
projectId: req.params.projectId,
actorPermissionDetails: req.permission,
tokenVersionId: req.auth.tokenVersionId
});
const appCfg = getConfig();
void res.setCookie("infisical-project-assume-privileges", payload.assumePrivilegesToken, {
httpOnly: true,
path: "/",
sameSite: "strict",
secure: appCfg.HTTPS_ENABLED,
maxAge: 3600 // 1 hour in seconds
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
event: {
type: EventType.PROJECT_ASSUME_PRIVILEGE_SESSION_START,
metadata: {
projectId: req.params.projectId,
requesterEmail: req.auth.user.username,
requesterId: req.auth.user.id,
targetActorType: req.body.actorType,
targetActorId: req.body.actorId,
duration: "1hr"
}
}
});
return { message: "Successfully assumed role" };
}
throw new BadRequestError({ message: "Invalid auth mode" });
}
});
server.route({
method: "DELETE",
url: "/:projectId/assume-privileges",
config: {
rateLimit: writeLimit
},
schema: {
params: z.object({
projectId: z.string()
}),
response: {
200: z.object({
message: z.string()
})
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req, res) => {
const assumedPrivilegeDetails = requestContext.get("assumedPrivilegeDetails");
if (req.auth.authMode === AuthMode.JWT && assumedPrivilegeDetails) {
const appCfg = getConfig();
void res.setCookie("infisical-project-assume-privileges", "", {
httpOnly: true,
path: "/",
sameSite: "strict",
secure: appCfg.HTTPS_ENABLED,
expires: new Date(0)
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
event: {
type: EventType.PROJECT_ASSUME_PRIVILEGE_SESSION_END,
metadata: {
projectId: req.params.projectId,
requesterEmail: req.auth.user.username,
requesterId: req.auth.user.id,
targetActorId: assumedPrivilegeDetails.actorId,
targetActorType: assumedPrivilegeDetails.actorType
}
}
});
return { message: "Successfully exited assumed role" };
}
throw new BadRequestError({ message: "Invalid auth mode" });
}
});
};

View File

@ -121,14 +121,7 @@ export const registerGatewayRouter = async (server: FastifyZodProvider) => {
identity: z.object({
name: z.string(),
id: z.string()
}),
projects: z
.object({
name: z.string(),
id: z.string(),
slug: z.string()
})
.array()
})
}).array()
})
}
@ -158,17 +151,15 @@ export const registerGatewayRouter = async (server: FastifyZodProvider) => {
identity: z.object({
name: z.string(),
id: z.string()
}),
projectGatewayId: z.string()
})
}).array()
})
}
},
onRequest: verifyAuth([AuthMode.IDENTITY_ACCESS_TOKEN, AuthMode.JWT]),
handler: async (req) => {
const gateways = await server.services.gateway.getProjectGateways({
projectId: req.params.projectId,
projectPermission: req.permission
const gateways = await server.services.gateway.listGateways({
orgPermission: req.permission
});
return { gateways };
}
@ -216,8 +207,7 @@ export const registerGatewayRouter = async (server: FastifyZodProvider) => {
id: z.string()
}),
body: z.object({
name: slugSchema({ field: "name" }).optional(),
projectIds: z.string().array().optional()
name: slugSchema({ field: "name" }).optional()
}),
response: {
200: z.object({
@ -230,8 +220,7 @@ export const registerGatewayRouter = async (server: FastifyZodProvider) => {
const gateway = await server.services.gateway.updateGatewayById({
orgPermission: req.permission,
id: req.params.id,
name: req.body.name,
projectIds: req.body.projectIds
name: req.body.name
});
return { gateway };
}

View File

@ -0,0 +1,129 @@
import { z } from "zod";
import { GithubOrgSyncConfigsSchema } from "@app/db/schemas";
import { CharacterType, zodValidateCharacters } from "@app/lib/validator/validate-string";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
const SanitizedGithubOrgSyncSchema = GithubOrgSyncConfigsSchema.pick({
isActive: true,
id: true,
createdAt: true,
updatedAt: true,
orgId: true,
githubOrgName: true
});
const githubOrgNameValidator = zodValidateCharacters([CharacterType.AlphaNumeric, CharacterType.Hyphen]);
export const registerGithubOrgSyncRouter = async (server: FastifyZodProvider) => {
server.route({
url: "/",
method: "POST",
config: {
rateLimit: writeLimit
},
onRequest: verifyAuth([AuthMode.JWT]),
schema: {
body: z.object({
githubOrgName: githubOrgNameValidator(z.string().trim(), "GitHub Org Name"),
githubOrgAccessToken: z.string().trim().max(1000).optional(),
isActive: z.boolean().default(false)
}),
response: {
200: z.object({
githubOrgSyncConfig: SanitizedGithubOrgSyncSchema
})
}
},
handler: async (req) => {
const githubOrgSyncConfig = await server.services.githubOrgSync.createGithubOrgSync({
orgPermission: req.permission,
githubOrgName: req.body.githubOrgName,
githubOrgAccessToken: req.body.githubOrgAccessToken,
isActive: req.body.isActive
});
return { githubOrgSyncConfig };
}
});
server.route({
url: "/",
method: "PATCH",
config: {
rateLimit: writeLimit
},
onRequest: verifyAuth([AuthMode.JWT]),
schema: {
body: z
.object({
githubOrgName: githubOrgNameValidator(z.string().trim(), "GitHub Org Name"),
githubOrgAccessToken: z.string().trim().max(1000),
isActive: z.boolean()
})
.partial(),
response: {
200: z.object({
githubOrgSyncConfig: SanitizedGithubOrgSyncSchema
})
}
},
handler: async (req) => {
const githubOrgSyncConfig = await server.services.githubOrgSync.updateGithubOrgSync({
orgPermission: req.permission,
githubOrgName: req.body.githubOrgName,
githubOrgAccessToken: req.body.githubOrgAccessToken,
isActive: req.body.isActive
});
return { githubOrgSyncConfig };
}
});
server.route({
url: "/",
method: "DELETE",
config: {
rateLimit: writeLimit
},
onRequest: verifyAuth([AuthMode.JWT]),
schema: {
response: {
200: z.object({
githubOrgSyncConfig: SanitizedGithubOrgSyncSchema
})
}
},
handler: async (req) => {
const githubOrgSyncConfig = await server.services.githubOrgSync.deleteGithubOrgSync({
orgPermission: req.permission
});
return { githubOrgSyncConfig };
}
});
server.route({
url: "/",
method: "GET",
config: {
rateLimit: readLimit
},
onRequest: verifyAuth([AuthMode.JWT]),
schema: {
response: {
200: z.object({
githubOrgSyncConfig: SanitizedGithubOrgSyncSchema
})
}
},
handler: async (req) => {
const githubOrgSyncConfig = await server.services.githubOrgSync.getGithubOrgSync({
orgPermission: req.permission
});
return { githubOrgSyncConfig };
}
});
};

View File

@ -2,12 +2,14 @@ import { registerProjectTemplateRouter } from "@app/ee/routes/v1/project-templat
import { registerAccessApprovalPolicyRouter } from "./access-approval-policy-router";
import { registerAccessApprovalRequestRouter } from "./access-approval-request-router";
import { registerAssumePrivilegeRouter } from "./assume-privilege-router";
import { registerAuditLogStreamRouter } from "./audit-log-stream-router";
import { registerCaCrlRouter } from "./certificate-authority-crl-router";
import { registerDynamicSecretLeaseRouter } from "./dynamic-secret-lease-router";
import { registerDynamicSecretRouter } from "./dynamic-secret-router";
import { registerExternalKmsRouter } from "./external-kms-router";
import { registerGatewayRouter } from "./gateway-router";
import { registerGithubOrgSyncRouter } from "./github-org-sync-router";
import { registerGroupRouter } from "./group-router";
import { registerIdentityProjectAdditionalPrivilegeRouter } from "./identity-project-additional-privilege-router";
import { registerKmipRouter } from "./kmip-router";
@ -32,6 +34,7 @@ import { registerSnapshotRouter } from "./snapshot-router";
import { registerSshCaRouter } from "./ssh-certificate-authority-router";
import { registerSshCertRouter } from "./ssh-certificate-router";
import { registerSshCertificateTemplateRouter } from "./ssh-certificate-template-router";
import { registerSshHostGroupRouter } from "./ssh-host-group-router";
import { registerSshHostRouter } from "./ssh-host-router";
import { registerTrustedIpRouter } from "./trusted-ip-router";
import { registerUserAdditionalPrivilegeRouter } from "./user-additional-privilege-router";
@ -45,6 +48,7 @@ export const registerV1EERoutes = async (server: FastifyZodProvider) => {
await projectRouter.register(registerProjectRoleRouter);
await projectRouter.register(registerProjectRouter);
await projectRouter.register(registerTrustedIpRouter);
await projectRouter.register(registerAssumePrivilegeRouter);
},
{ prefix: "/workspace" }
);
@ -70,6 +74,7 @@ export const registerV1EERoutes = async (server: FastifyZodProvider) => {
);
await server.register(registerGatewayRouter, { prefix: "/gateways" });
await server.register(registerGithubOrgSyncRouter, { prefix: "/github-org-sync-config" });
await server.register(
async (pkiRouter) => {
@ -84,6 +89,7 @@ export const registerV1EERoutes = async (server: FastifyZodProvider) => {
await sshRouter.register(registerSshCertRouter, { prefix: "/certificates" });
await sshRouter.register(registerSshCertificateTemplateRouter, { prefix: "/certificate-templates" });
await sshRouter.register(registerSshHostRouter, { prefix: "/hosts" });
await sshRouter.register(registerSshHostGroupRouter, { prefix: "/host-groups" });
},
{ prefix: "/ssh" }
);

View File

@ -98,6 +98,9 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
server.route({
url: "/login",
method: "POST",
config: {
rateLimit: writeLimit
},
schema: {
body: z.object({
organizationSlug: z.string().trim()

View File

@ -47,7 +47,7 @@ export const registerLicenseRouter = async (server: FastifyZodProvider) => {
200: z.object({ plan: z.any() })
}
},
onRequest: verifyAuth([AuthMode.JWT]),
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const plan = await server.services.license.getOrgPlan({
actorId: req.permission.id,

View File

@ -1,7 +1,7 @@
import { packRules } from "@casl/ability/extra";
import { z } from "zod";
import { ProjectMembershipRole, ProjectMembershipsSchema, ProjectRolesSchema } from "@app/db/schemas";
import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas";
import {
backfillPermissionV1SchemaToV2Schema,
ProjectPermissionV1Schema
@ -245,13 +245,22 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
response: {
200: z.object({
data: z.object({
membership: ProjectMembershipsSchema.extend({
membership: z.object({
id: z.string(),
roles: z
.object({
role: z.string()
})
.array()
}),
assumedPrivilegeDetails: z
.object({
actorId: z.string(),
actorType: z.string(),
actorName: z.string(),
actorEmail: z.string().optional()
})
.optional(),
permissions: z.any().array()
})
})
@ -259,14 +268,20 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { permissions, membership } = await server.services.projectRole.getUserPermission(
const { permissions, membership, assumedPrivilegeDetails } = await server.services.projectRole.getUserPermission(
req.permission.id,
req.params.projectId,
req.permission.authMethod,
req.permission.orgId
);
return { data: { permissions, membership } };
return {
data: {
permissions,
membership,
assumedPrivilegeDetails
}
};
}
});
};

View File

@ -1,9 +1,8 @@
import { z } from "zod";
import { ProjectMembershipRole, ProjectTemplatesSchema } from "@app/db/schemas";
import { ProjectMembershipRole, ProjectTemplatesSchema, ProjectType } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
import { ProjectTemplateDefaultEnvironments } from "@app/ee/services/project-template/project-template-constants";
import { isInfisicalProjectTemplate } from "@app/ee/services/project-template/project-template-fns";
import { ApiDocsTags, ProjectTemplates } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
@ -35,6 +34,7 @@ const SanitizedProjectTemplateSchema = ProjectTemplatesSchema.extend({
position: z.number().min(1)
})
.array()
.nullable()
});
const ProjectTemplateRolesSchema = z
@ -104,6 +104,9 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
hide: false,
tags: [ApiDocsTags.ProjectTemplates],
description: "List project templates for the current organization.",
querystring: z.object({
type: z.nativeEnum(ProjectType).optional().describe(ProjectTemplates.LIST.type)
}),
response: {
200: z.object({
projectTemplates: SanitizedProjectTemplateSchema.array()
@ -112,7 +115,8 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const projectTemplates = await server.services.projectTemplate.listProjectTemplatesByOrg(req.permission);
const { type } = req.query;
const projectTemplates = await server.services.projectTemplate.listProjectTemplatesByOrg(req.permission, type);
const auditTemplates = projectTemplates.filter((template) => !isInfisicalProjectTemplate(template.name));
@ -184,6 +188,7 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
tags: [ApiDocsTags.ProjectTemplates],
description: "Create a project template.",
body: z.object({
type: z.nativeEnum(ProjectType).describe(ProjectTemplates.CREATE.type),
name: slugSchema({ field: "name" })
.refine((val) => !isInfisicalProjectTemplate(val), {
message: `The requested project template name is reserved.`
@ -191,9 +196,7 @@ export const registerProjectTemplateRouter = async (server: FastifyZodProvider)
.describe(ProjectTemplates.CREATE.name),
description: z.string().max(256).trim().optional().describe(ProjectTemplates.CREATE.description),
roles: ProjectTemplateRolesSchema.default([]).describe(ProjectTemplates.CREATE.roles),
environments: ProjectTemplateEnvironmentsSchema.default(ProjectTemplateDefaultEnvironments).describe(
ProjectTemplates.CREATE.environments
)
environments: ProjectTemplateEnvironmentsSchema.describe(ProjectTemplates.CREATE.environments).optional()
}),
response: {
200: z.object({

View File

@ -145,7 +145,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
const { isUserCompleted, providerAuthToken } = await server.services.saml.samlLogin({
externalId: profile.nameID,
email,
email: email.toLowerCase(),
firstName,
lastName: lastName as string,
relayState: (req.body as { RelayState?: string }).RelayState,
@ -166,6 +166,9 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
server.route({
url: "/redirect/saml2/organizations/:orgSlug",
method: "GET",
config: {
rateLimit: readLimit
},
schema: {
params: z.object({
orgSlug: z.string().trim()
@ -192,6 +195,9 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
server.route({
url: "/redirect/saml2/:samlConfigId",
method: "GET",
config: {
rateLimit: readLimit
},
schema: {
params: z.object({
samlConfigId: z.string().trim()
@ -218,6 +224,9 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
server.route({
url: "/saml2/:samlConfigId",
method: "POST",
config: {
rateLimit: writeLimit
},
schema: {
params: z.object({
samlConfigId: z.string().trim()

View File

@ -196,6 +196,9 @@ export const registerScimRouter = async (server: FastifyZodProvider) => {
server.route({
url: "/Users",
method: "POST",
config: {
rateLimit: writeLimit
},
schema: {
body: z.object({
schemas: z.array(z.string()),

View File

@ -1,11 +1,11 @@
import { z } from "zod";
import { GitAppOrgSchema, SecretScanningGitRisksSchema } from "@app/db/schemas";
import { canUseSecretScanning } from "@app/ee/services/secret-scanning/secret-scanning-fns";
import {
SecretScanningResolvedStatus,
SecretScanningRiskStatus
} from "@app/ee/services/secret-scanning/secret-scanning-types";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError } from "@app/lib/errors";
import { OrderByDirection } from "@app/lib/types";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
@ -23,14 +23,14 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
body: z.object({ organizationId: z.string().trim() }),
response: {
200: z.object({
sessionId: z.string()
sessionId: z.string(),
gitAppSlug: z.string()
})
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const appCfg = getConfig();
if (!appCfg.SECRET_SCANNING_ORG_WHITELIST?.includes(req.auth.orgId)) {
if (!canUseSecretScanning(req.auth.orgId)) {
throw new BadRequestError({
message: "Secret scanning is temporarily unavailable."
});

View File

@ -0,0 +1,16 @@
import {
CreateOCIVaultSyncSchema,
OCIVaultSyncSchema,
UpdateOCIVaultSyncSchema
} from "@app/ee/services/secret-sync/oci-vault";
import { registerSyncSecretsEndpoints } from "@app/server/routes/v1/secret-sync-routers/secret-sync-endpoints";
import { SecretSync } from "@app/services/secret-sync/secret-sync-enums";
export const registerOCIVaultSyncRouter = async (server: FastifyZodProvider) =>
registerSyncSecretsEndpoints({
destination: SecretSync.OCIVault,
server,
responseSchema: OCIVaultSyncSchema,
createSchema: CreateOCIVaultSyncSchema,
updateSchema: UpdateOCIVaultSyncSchema
});

View File

@ -97,7 +97,7 @@ export const registerSshCertificateTemplateRouter = async (server: FastifyZodPro
allowCustomKeyIds: z.boolean().describe(SSH_CERTIFICATE_TEMPLATES.CREATE.allowCustomKeyIds)
})
.refine((data) => ms(data.maxTTL) >= ms(data.ttl), {
message: "Max TLL must be greater than or equal to TTL",
message: "Max TTL must be greater than or equal to TTL",
path: ["maxTTL"]
}),
response: {

View File

@ -0,0 +1,360 @@
import { z } from "zod";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { loginMappingSchema, sanitizedSshHost } from "@app/ee/services/ssh-host/ssh-host-schema";
import { sanitizedSshHostGroup } from "@app/ee/services/ssh-host-group/ssh-host-group-schema";
import { EHostGroupMembershipFilter } from "@app/ee/services/ssh-host-group/ssh-host-group-types";
import { ApiDocsTags, SSH_HOST_GROUPS } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { slugSchema } from "@app/server/lib/schemas";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
export const registerSshHostGroupRouter = async (server: FastifyZodProvider) => {
server.route({
method: "GET",
url: "/:sshHostGroupId",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHostGroups],
description: "Get SSH Host Group",
params: z.object({
sshHostGroupId: z.string().describe(SSH_HOST_GROUPS.GET.sshHostGroupId)
}),
response: {
200: sanitizedSshHostGroup.extend({
loginMappings: z.array(loginMappingSchema)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const sshHostGroup = await server.services.sshHostGroup.getSshHostGroup({
sshHostGroupId: req.params.sshHostGroupId,
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: sshHostGroup.projectId,
event: {
type: EventType.GET_SSH_HOST_GROUP,
metadata: {
sshHostGroupId: sshHostGroup.id,
name: sshHostGroup.name
}
}
});
return sshHostGroup;
}
});
server.route({
method: "POST",
url: "/",
config: {
rateLimit: writeLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHostGroups],
description: "Create SSH Host Group",
body: z.object({
projectId: z.string().describe(SSH_HOST_GROUPS.CREATE.projectId),
name: slugSchema({ min: 1, max: 64, field: "name" }).describe(SSH_HOST_GROUPS.CREATE.name),
loginMappings: z.array(loginMappingSchema).default([]).describe(SSH_HOST_GROUPS.CREATE.loginMappings)
}),
response: {
200: sanitizedSshHostGroup.extend({
loginMappings: z.array(loginMappingSchema)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const sshHostGroup = await server.services.sshHostGroup.createSshHostGroup({
...req.body,
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: sshHostGroup.projectId,
event: {
type: EventType.CREATE_SSH_HOST_GROUP,
metadata: {
sshHostGroupId: sshHostGroup.id,
name: sshHostGroup.name,
loginMappings: sshHostGroup.loginMappings
}
}
});
return sshHostGroup;
}
});
server.route({
method: "PATCH",
url: "/:sshHostGroupId",
config: {
rateLimit: writeLimit
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: {
hide: false,
tags: [ApiDocsTags.SshHostGroups],
description: "Update SSH Host Group",
params: z.object({
sshHostGroupId: z.string().trim().describe(SSH_HOST_GROUPS.UPDATE.sshHostGroupId)
}),
body: z.object({
name: slugSchema({ min: 1, max: 64, field: "name" }).describe(SSH_HOST_GROUPS.UPDATE.name).optional(),
loginMappings: z.array(loginMappingSchema).optional().describe(SSH_HOST_GROUPS.UPDATE.loginMappings)
}),
response: {
200: sanitizedSshHostGroup.extend({
loginMappings: z.array(loginMappingSchema)
})
}
},
handler: async (req) => {
const sshHostGroup = await server.services.sshHostGroup.updateSshHostGroup({
sshHostGroupId: req.params.sshHostGroupId,
...req.body,
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: sshHostGroup.projectId,
event: {
type: EventType.UPDATE_SSH_HOST_GROUP,
metadata: {
sshHostGroupId: sshHostGroup.id,
name: sshHostGroup.name,
loginMappings: sshHostGroup.loginMappings
}
}
});
return sshHostGroup;
}
});
server.route({
method: "DELETE",
url: "/:sshHostGroupId",
config: {
rateLimit: writeLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHostGroups],
description: "Delete SSH Host Group",
params: z.object({
sshHostGroupId: z.string().describe(SSH_HOST_GROUPS.DELETE.sshHostGroupId)
}),
response: {
200: sanitizedSshHostGroup.extend({
loginMappings: z.array(loginMappingSchema)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const sshHostGroup = await server.services.sshHostGroup.deleteSshHostGroup({
sshHostGroupId: req.params.sshHostGroupId,
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: sshHostGroup.projectId,
event: {
type: EventType.DELETE_SSH_HOST_GROUP,
metadata: {
sshHostGroupId: sshHostGroup.id,
name: sshHostGroup.name
}
}
});
return sshHostGroup;
}
});
server.route({
method: "GET",
url: "/:sshHostGroupId/hosts",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHostGroups],
description: "Get SSH Hosts in a Host Group",
params: z.object({
sshHostGroupId: z.string().describe(SSH_HOST_GROUPS.GET.sshHostGroupId)
}),
querystring: z.object({
filter: z.nativeEnum(EHostGroupMembershipFilter).optional().describe(SSH_HOST_GROUPS.GET.filter)
}),
response: {
200: z.object({
hosts: sanitizedSshHost
.pick({
id: true,
hostname: true,
alias: true
})
.merge(
z.object({
isPartOfGroup: z.boolean(),
joinedGroupAt: z.date().nullable()
})
)
.array(),
totalCount: z.number()
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { sshHostGroup, hosts, totalCount } = await server.services.sshHostGroup.listSshHostGroupHosts({
sshHostGroupId: req.params.sshHostGroupId,
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
...req.query
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: sshHostGroup.projectId,
event: {
type: EventType.GET_SSH_HOST_GROUP_HOSTS,
metadata: {
sshHostGroupId: req.params.sshHostGroupId,
name: sshHostGroup.name
}
}
});
return { hosts, totalCount };
}
});
server.route({
method: "POST",
url: "/:sshHostGroupId/hosts/:hostId",
config: {
rateLimit: writeLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHostGroups],
description: "Add an SSH Host to a Host Group",
params: z.object({
sshHostGroupId: z.string().describe(SSH_HOST_GROUPS.ADD_HOST.sshHostGroupId),
hostId: z.string().describe(SSH_HOST_GROUPS.ADD_HOST.hostId)
}),
response: {
200: sanitizedSshHost.extend({
loginMappings: z.array(loginMappingSchema)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { sshHostGroup, sshHost } = await server.services.sshHostGroup.addHostToSshHostGroup({
sshHostGroupId: req.params.sshHostGroupId,
hostId: req.params.hostId,
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: sshHost.projectId,
event: {
type: EventType.ADD_HOST_TO_SSH_HOST_GROUP,
metadata: {
sshHostGroupId: sshHostGroup.id,
sshHostId: sshHost.id,
hostname: sshHost.hostname
}
}
});
return sshHost;
}
});
server.route({
method: "DELETE",
url: "/:sshHostGroupId/hosts/:hostId",
config: {
rateLimit: writeLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHostGroups],
description: "Remove an SSH Host from a Host Group",
params: z.object({
sshHostGroupId: z.string().describe(SSH_HOST_GROUPS.DELETE_HOST.sshHostGroupId),
hostId: z.string().describe(SSH_HOST_GROUPS.DELETE_HOST.hostId)
}),
response: {
200: sanitizedSshHost.extend({
loginMappings: z.array(loginMappingSchema)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { sshHostGroup, sshHost } = await server.services.sshHostGroup.removeHostFromSshHostGroup({
sshHostGroupId: req.params.sshHostGroupId,
hostId: req.params.hostId,
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: sshHost.projectId,
event: {
type: EventType.REMOVE_HOST_FROM_SSH_HOST_GROUP,
metadata: {
sshHostGroupId: sshHostGroup.id,
sshHostId: sshHost.id,
hostname: sshHost.hostname
}
}
});
return sshHost;
}
});
};

View File

@ -3,10 +3,12 @@ import { z } from "zod";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { SshCertKeyAlgorithm } from "@app/ee/services/ssh-certificate/ssh-certificate-types";
import { loginMappingSchema, sanitizedSshHost } from "@app/ee/services/ssh-host/ssh-host-schema";
import { LoginMappingSource } from "@app/ee/services/ssh-host/ssh-host-types";
import { isValidHostname } from "@app/ee/services/ssh-host/ssh-host-validators";
import { SSH_HOSTS } from "@app/lib/api-docs";
import { ApiDocsTags, SSH_HOSTS } from "@app/lib/api-docs";
import { ms } from "@app/lib/ms";
import { publicSshCaLimit, readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { slugSchema } from "@app/server/lib/schemas";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
@ -20,10 +22,16 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHosts],
response: {
200: z.array(
sanitizedSshHost.extend({
loginMappings: z.array(loginMappingSchema)
loginMappings: loginMappingSchema
.extend({
source: z.nativeEnum(LoginMappingSource)
})
.array()
})
)
}
@ -48,18 +56,24 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHosts],
params: z.object({
sshHostId: z.string().describe(SSH_HOSTS.GET.sshHostId)
}),
response: {
200: sanitizedSshHost.extend({
loginMappings: z.array(loginMappingSchema)
loginMappings: loginMappingSchema
.extend({
source: z.nativeEnum(LoginMappingSource)
})
.array()
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const host = await server.services.sshHost.getSshHost({
const host = await server.services.sshHost.getSshHostById({
sshHostId: req.params.sshHostId,
actor: req.permission.type,
actorId: req.permission.id,
@ -90,16 +104,20 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit
},
schema: {
description: "Add an SSH Host",
hide: false,
tags: [ApiDocsTags.SshHosts],
description: "Register SSH Host",
body: z.object({
projectId: z.string().describe(SSH_HOSTS.CREATE.projectId),
hostname: z
.string()
.min(1)
.trim()
.refine((v) => isValidHostname(v), {
message: "Hostname must be a valid hostname"
})
.describe(SSH_HOSTS.CREATE.hostname),
alias: slugSchema({ min: 0, max: 64, field: "alias" }).describe(SSH_HOSTS.CREATE.alias).default(""),
userCertTtl: z
.string()
.refine((val) => ms(val) > 0, "TTL must be a positive number")
@ -116,7 +134,11 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
}),
response: {
200: sanitizedSshHost.extend({
loginMappings: z.array(loginMappingSchema)
loginMappings: loginMappingSchema
.extend({
source: z.nativeEnum(LoginMappingSource)
})
.array()
})
}
},
@ -138,6 +160,7 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
metadata: {
sshHostId: host.id,
hostname: host.hostname,
alias: host.alias ?? null,
userCertTtl: host.userCertTtl,
hostCertTtl: host.hostCertTtl,
loginMappings: host.loginMappings,
@ -159,6 +182,8 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: {
hide: false,
tags: [ApiDocsTags.SshHosts],
description: "Update SSH Host",
params: z.object({
sshHostId: z.string().trim().describe(SSH_HOSTS.UPDATE.sshHostId)
@ -166,12 +191,14 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
body: z.object({
hostname: z
.string()
.trim()
.min(1)
.refine((v) => isValidHostname(v), {
message: "Hostname must be a valid hostname"
})
.optional()
.describe(SSH_HOSTS.UPDATE.hostname),
alias: slugSchema({ min: 0, max: 64, field: "alias" }).describe(SSH_HOSTS.UPDATE.alias).optional(),
userCertTtl: z
.string()
.refine((val) => ms(val) > 0, "TTL must be a positive number")
@ -186,7 +213,11 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
}),
response: {
200: sanitizedSshHost.extend({
loginMappings: z.array(loginMappingSchema)
loginMappings: loginMappingSchema
.extend({
source: z.nativeEnum(LoginMappingSource)
})
.array()
})
}
},
@ -208,6 +239,7 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
metadata: {
sshHostId: host.id,
hostname: host.hostname,
alias: host.alias,
userCertTtl: host.userCertTtl,
hostCertTtl: host.hostCertTtl,
loginMappings: host.loginMappings,
@ -228,12 +260,19 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
rateLimit: writeLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHosts],
description: "Delete SSH Host",
params: z.object({
sshHostId: z.string().describe(SSH_HOSTS.DELETE.sshHostId)
}),
response: {
200: sanitizedSshHost.extend({
loginMappings: z.array(loginMappingSchema)
loginMappings: loginMappingSchema
.extend({
source: z.nativeEnum(LoginMappingSource)
})
.array()
})
}
},
@ -271,6 +310,8 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT]),
schema: {
hide: false,
tags: [ApiDocsTags.SshHosts],
description: "Issue SSH certificate for user",
params: z.object({
sshHostId: z.string().describe(SSH_HOSTS.ISSUE_SSH_CREDENTIALS.sshHostId)
@ -343,6 +384,8 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: {
hide: false,
tags: [ApiDocsTags.SshHosts],
description: "Issue SSH certificate for host",
params: z.object({
sshHostId: z.string().describe(SSH_HOSTS.ISSUE_HOST_CERT.sshHostId)
@ -407,6 +450,8 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
rateLimit: publicSshCaLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHosts],
description: "Get public key of the user SSH CA linked to the host",
params: z.object({
sshHostId: z.string().trim().describe(SSH_HOSTS.GET_USER_CA_PUBLIC_KEY.sshHostId)
@ -428,6 +473,8 @@ export const registerSshHostRouter = async (server: FastifyZodProvider) => {
rateLimit: publicSshCaLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHosts],
description: "Get public key of the host SSH CA linked to the host",
params: z.object({
sshHostId: z.string().trim().describe(SSH_HOSTS.GET_HOST_CA_PUBLIC_KEY.sshHostId)

View File

@ -0,0 +1,19 @@
import {
AzureClientSecretRotationGeneratedCredentialsSchema,
AzureClientSecretRotationSchema,
CreateAzureClientSecretRotationSchema,
UpdateAzureClientSecretRotationSchema
} from "@app/ee/services/secret-rotation-v2/azure-client-secret";
import { SecretRotation } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-enums";
import { registerSecretRotationEndpoints } from "./secret-rotation-v2-endpoints";
export const registerAzureClientSecretRotationRouter = async (server: FastifyZodProvider) =>
registerSecretRotationEndpoints({
type: SecretRotation.AzureClientSecret,
server,
responseSchema: AzureClientSecretRotationSchema,
createSchema: CreateAzureClientSecretRotationSchema,
updateSchema: UpdateAzureClientSecretRotationSchema,
generatedCredentialsSchema: AzureClientSecretRotationGeneratedCredentialsSchema
});

View File

@ -2,6 +2,8 @@ import { SecretRotation } from "@app/ee/services/secret-rotation-v2/secret-rotat
import { registerAuth0ClientSecretRotationRouter } from "./auth0-client-secret-rotation-router";
import { registerAwsIamUserSecretRotationRouter } from "./aws-iam-user-secret-rotation-router";
import { registerAzureClientSecretRotationRouter } from "./azure-client-secret-rotation-router";
import { registerLdapPasswordRotationRouter } from "./ldap-password-rotation-router";
import { registerMsSqlCredentialsRotationRouter } from "./mssql-credentials-rotation-router";
import { registerPostgresCredentialsRotationRouter } from "./postgres-credentials-rotation-router";
@ -14,5 +16,7 @@ export const SECRET_ROTATION_REGISTER_ROUTER_MAP: Record<
[SecretRotation.PostgresCredentials]: registerPostgresCredentialsRotationRouter,
[SecretRotation.MsSqlCredentials]: registerMsSqlCredentialsRotationRouter,
[SecretRotation.Auth0ClientSecret]: registerAuth0ClientSecretRotationRouter,
[SecretRotation.AwsIamUserSecret]: registerAwsIamUserSecretRotationRouter
[SecretRotation.AzureClientSecret]: registerAzureClientSecretRotationRouter,
[SecretRotation.AwsIamUserSecret]: registerAwsIamUserSecretRotationRouter,
[SecretRotation.LdapPassword]: registerLdapPasswordRotationRouter
};

View File

@ -0,0 +1,19 @@
import {
CreateLdapPasswordRotationSchema,
LdapPasswordRotationGeneratedCredentialsSchema,
LdapPasswordRotationSchema,
UpdateLdapPasswordRotationSchema
} from "@app/ee/services/secret-rotation-v2/ldap-password";
import { SecretRotation } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-enums";
import { registerSecretRotationEndpoints } from "./secret-rotation-v2-endpoints";
export const registerLdapPasswordRotationRouter = async (server: FastifyZodProvider) =>
registerSecretRotationEndpoints({
type: SecretRotation.LdapPassword,
server,
responseSchema: LdapPasswordRotationSchema,
createSchema: CreateLdapPasswordRotationSchema,
updateSchema: UpdateLdapPasswordRotationSchema,
generatedCredentialsSchema: LdapPasswordRotationGeneratedCredentialsSchema
});

View File

@ -3,6 +3,8 @@ import { z } from "zod";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { Auth0ClientSecretRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/auth0-client-secret";
import { AwsIamUserSecretRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/aws-iam-user-secret";
import { AzureClientSecretRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/azure-client-secret";
import { LdapPasswordRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/ldap-password";
import { MsSqlCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/mssql-credentials";
import { PostgresCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/postgres-credentials";
import { SecretRotationV2Schema } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema";
@ -15,7 +17,9 @@ const SecretRotationV2OptionsSchema = z.discriminatedUnion("type", [
PostgresCredentialsRotationListItemSchema,
MsSqlCredentialsRotationListItemSchema,
Auth0ClientSecretRotationListItemSchema,
AwsIamUserSecretRotationListItemSchema
AzureClientSecretRotationListItemSchema,
AwsIamUserSecretRotationListItemSchema,
LdapPasswordRotationListItemSchema
]);
export const registerSecretRotationV2Router = async (server: FastifyZodProvider) => {

View File

@ -2,7 +2,7 @@ import { ForbiddenError } from "@casl/ability";
import { ActionProjectType } from "@app/db/schemas";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { ProjectPermissionApprovalActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
import { TProjectDALFactory } from "@app/services/project/project-dal";
import { TProjectEnvDALFactory } from "@app/services/project-env/project-env-dal";
@ -98,7 +98,7 @@ export const accessApprovalPolicyServiceFactory = ({
});
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create,
ProjectPermissionApprovalActions.Create,
ProjectPermissionSub.SecretApproval
);
const env = await projectEnvDAL.findOne({ slug: environment, projectId: project.id });
@ -256,7 +256,10 @@ export const accessApprovalPolicyServiceFactory = ({
actionProjectType: ActionProjectType.SecretManager
});
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionApprovalActions.Edit,
ProjectPermissionSub.SecretApproval
);
const updatedPolicy = await accessApprovalPolicyDAL.transaction(async (tx) => {
const doc = await accessApprovalPolicyDAL.updateById(
@ -341,7 +344,7 @@ export const accessApprovalPolicyServiceFactory = ({
actionProjectType: ActionProjectType.SecretManager
});
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete,
ProjectPermissionApprovalActions.Delete,
ProjectPermissionSub.SecretApproval
);
@ -432,7 +435,10 @@ export const accessApprovalPolicyServiceFactory = ({
actionProjectType: ActionProjectType.SecretManager
});
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionApprovalActions.Read,
ProjectPermissionSub.SecretApproval
);
return policy;
};

View File

@ -6,13 +6,16 @@ import { getConfig } from "@app/lib/config/env";
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
import { ms } from "@app/lib/ms";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { EnforcementLevel } from "@app/lib/types";
import { triggerWorkflowIntegrationNotification } from "@app/lib/workflow-integrations/trigger-notification";
import { TriggerFeature } from "@app/lib/workflow-integrations/types";
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TMicrosoftTeamsServiceFactory } from "@app/services/microsoft-teams/microsoft-teams-service";
import { TProjectMicrosoftTeamsConfigDALFactory } from "@app/services/microsoft-teams/project-microsoft-teams-config-dal";
import { TProjectDALFactory } from "@app/services/project/project-dal";
import { TProjectEnvDALFactory } from "@app/services/project-env/project-env-dal";
import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal";
import { TProjectSlackConfigDALFactory } from "@app/services/slack/project-slack-config-dal";
import { triggerSlackNotification } from "@app/services/slack/slack-fns";
import { SlackTriggerFeature } from "@app/services/slack/slack-types";
import { SmtpTemplates, TSmtpService } from "@app/services/smtp/smtp-service";
import { TUserDALFactory } from "@app/services/user/user-dal";
@ -20,6 +23,7 @@ import { TAccessApprovalPolicyApproverDALFactory } from "../access-approval-poli
import { TAccessApprovalPolicyDALFactory } from "../access-approval-policy/access-approval-policy-dal";
import { TGroupDALFactory } from "../group/group-dal";
import { TPermissionServiceFactory } from "../permission/permission-service";
import { ProjectPermissionApprovalActions, ProjectPermissionSub } from "../permission/project-permission";
import { TProjectUserAdditionalPrivilegeDALFactory } from "../project-user-additional-privilege/project-user-additional-privilege-dal";
import { ProjectUserAdditionalPrivilegeTemporaryMode } from "../project-user-additional-privilege/project-user-additional-privilege-types";
import { TAccessApprovalRequestDALFactory } from "./access-approval-request-dal";
@ -67,6 +71,8 @@ type TSecretApprovalRequestServiceFactoryDep = {
>;
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
projectSlackConfigDAL: Pick<TProjectSlackConfigDALFactory, "getIntegrationDetailsByProject">;
microsoftTeamsService: Pick<TMicrosoftTeamsServiceFactory, "sendNotification">;
projectMicrosoftTeamsConfigDAL: Pick<TProjectMicrosoftTeamsConfigDALFactory, "getIntegrationDetailsByProject">;
};
export type TAccessApprovalRequestServiceFactory = ReturnType<typeof accessApprovalRequestServiceFactory>;
@ -84,6 +90,8 @@ export const accessApprovalRequestServiceFactory = ({
smtpService,
userDAL,
kmsService,
microsoftTeamsService,
projectMicrosoftTeamsConfigDAL,
projectSlackConfigDAL
}: TSecretApprovalRequestServiceFactoryDep) => {
const createAccessApprovalRequest = async ({
@ -219,24 +227,30 @@ export const accessApprovalRequestServiceFactory = ({
const requesterFullName = `${requestedByUser.firstName} ${requestedByUser.lastName}`;
const approvalUrl = `${cfg.SITE_URL}/secret-manager/${project.id}/approval`;
await triggerSlackNotification({
projectId: project.id,
projectSlackConfigDAL,
projectDAL,
kmsService,
notification: {
type: SlackTriggerFeature.ACCESS_REQUEST,
payload: {
projectName: project.name,
requesterFullName,
isTemporary,
requesterEmail: requestedByUser.email as string,
secretPath,
environment: envSlug,
permissions: accessTypes,
approvalUrl,
note
}
await triggerWorkflowIntegrationNotification({
input: {
notification: {
type: TriggerFeature.ACCESS_REQUEST,
payload: {
projectName: project.name,
requesterFullName,
isTemporary,
requesterEmail: requestedByUser.email as string,
secretPath,
environment: envSlug,
permissions: accessTypes,
approvalUrl,
note
}
},
projectId: project.id
},
dependencies: {
projectDAL,
projectSlackConfigDAL,
kmsService,
microsoftTeamsService,
projectMicrosoftTeamsConfigDAL
}
});
@ -311,26 +325,22 @@ export const accessApprovalRequestServiceFactory = ({
status,
actorId,
actorAuthMethod,
actorOrgId
actorOrgId,
bypassReason
}: TReviewAccessRequestDTO) => {
const accessApprovalRequest = await accessApprovalRequestDAL.findById(requestId);
if (!accessApprovalRequest) {
throw new NotFoundError({ message: `Secret approval request with ID '${requestId}' not found` });
}
const { policy } = accessApprovalRequest;
const { policy, environment } = accessApprovalRequest;
if (policy.deletedAt) {
throw new BadRequestError({
message: "The policy associated with this access request has been deleted."
});
}
if (!policy.allowedSelfApprovals && actorId === accessApprovalRequest.requestedByUserId) {
throw new BadRequestError({
message: "Failed to review access approval request. Users are not authorized to review their own request."
});
}
const { membership, hasRole } = await permissionService.getProjectPermission({
const { membership, hasRole, permission } = await permissionService.getProjectPermission({
actor,
actorId,
projectId: accessApprovalRequest.projectId,
@ -343,6 +353,20 @@ export const accessApprovalRequestServiceFactory = ({
throw new ForbiddenRequestError({ message: "You are not a member of this project" });
}
const isSelfApproval = actorId === accessApprovalRequest.requestedByUserId;
const isSoftEnforcement = policy.enforcementLevel === EnforcementLevel.Soft;
const canBypassApproval = permission.can(
ProjectPermissionApprovalActions.AllowAccessBypass,
ProjectPermissionSub.SecretApproval
);
const cannotBypassUnderSoftEnforcement = !(isSoftEnforcement && canBypassApproval);
if (!policy.allowedSelfApprovals && isSelfApproval && cannotBypassUnderSoftEnforcement) {
throw new BadRequestError({
message: "Failed to review access approval request. Users are not authorized to review their own request."
});
}
if (
!hasRole(ProjectMembershipRole.Admin) &&
accessApprovalRequest.requestedByUserId !== actorId && // The request wasn't made by the current user
@ -351,21 +375,49 @@ export const accessApprovalRequestServiceFactory = ({
throw new ForbiddenRequestError({ message: "You are not authorized to approve this request" });
}
const project = await projectDAL.findById(accessApprovalRequest.projectId);
if (!project) {
throw new NotFoundError({ message: "The project associated with this access request was not found." });
}
const existingReviews = await accessApprovalRequestReviewerDAL.find({ requestId: accessApprovalRequest.id });
if (existingReviews.some((review) => review.status === ApprovalStatus.REJECTED)) {
throw new BadRequestError({ message: "The request has already been rejected by another reviewer" });
}
const reviewStatus = await accessApprovalRequestReviewerDAL.transaction(async (tx) => {
const review = await accessApprovalRequestReviewerDAL.findOne(
const isBreakGlassApprovalAttempt =
policy.enforcementLevel === EnforcementLevel.Soft &&
actorId === accessApprovalRequest.requestedByUserId &&
status === ApprovalStatus.APPROVED;
let reviewForThisActorProcessing: {
id: string;
requestId: string;
reviewerUserId: string;
status: string;
createdAt: Date;
updatedAt: Date;
};
const existingReviewByActorInTx = await accessApprovalRequestReviewerDAL.findOne(
{
requestId: accessApprovalRequest.id,
reviewerUserId: actorId
},
tx
);
if (!review) {
const newReview = await accessApprovalRequestReviewerDAL.create(
// Check if review exists for actor
if (existingReviewByActorInTx) {
// Check if breakglass re-approval
if (isBreakGlassApprovalAttempt && existingReviewByActorInTx.status === ApprovalStatus.APPROVED) {
reviewForThisActorProcessing = existingReviewByActorInTx;
} else {
throw new BadRequestError({ message: "You have already reviewed this request" });
}
} else {
reviewForThisActorProcessing = await accessApprovalRequestReviewerDAL.create(
{
status,
requestId: accessApprovalRequest.id,
@ -373,19 +425,26 @@ export const accessApprovalRequestServiceFactory = ({
},
tx
);
}
const allReviews = [...existingReviews, newReview];
const otherReviews = existingReviews.filter((er) => er.reviewerUserId !== actorId);
const allUniqueReviews = [...otherReviews, reviewForThisActorProcessing];
const approvedReviews = allReviews.filter((r) => r.status === ApprovalStatus.APPROVED);
const approvedReviews = allUniqueReviews.filter((r) => r.status === ApprovalStatus.APPROVED);
const meetsStandardApprovalThreshold = approvedReviews.length >= policy.approvals;
// approvals is the required number of approvals. If the number of approved reviews is equal to the number of required approvals, then the request is approved.
if (approvedReviews.length === policy.approvals) {
if (
reviewForThisActorProcessing.status === ApprovalStatus.APPROVED &&
(meetsStandardApprovalThreshold || isBreakGlassApprovalAttempt)
) {
const currentRequestState = await accessApprovalRequestDAL.findById(accessApprovalRequest.id, tx);
let privilegeIdToSet = currentRequestState?.privilegeId || null;
if (!privilegeIdToSet) {
if (accessApprovalRequest.isTemporary && !accessApprovalRequest.temporaryRange) {
throw new BadRequestError({ message: "Temporary range is required for temporary access" });
}
let privilegeId: string | null = null;
if (!accessApprovalRequest.isTemporary && !accessApprovalRequest.temporaryRange) {
// Permanent access
const privilege = await additionalPrivilegeDAL.create(
@ -397,7 +456,7 @@ export const accessApprovalRequestServiceFactory = ({
},
tx
);
privilegeId = privilege.id;
privilegeIdToSet = privilege.id;
} else {
// Temporary access
const relativeTempAllocatedTimeInMs = ms(accessApprovalRequest.temporaryRange!);
@ -409,23 +468,57 @@ export const accessApprovalRequestServiceFactory = ({
projectId: accessApprovalRequest.projectId,
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
permissions: JSON.stringify(accessApprovalRequest.permissions),
isTemporary: true,
isTemporary: true, // Explicitly set to true for the privilege
temporaryMode: ProjectUserAdditionalPrivilegeTemporaryMode.Relative,
temporaryRange: accessApprovalRequest.temporaryRange!,
temporaryAccessStartTime: startTime,
temporaryAccessEndTime: new Date(new Date(startTime).getTime() + relativeTempAllocatedTimeInMs)
temporaryAccessEndTime: new Date(startTime.getTime() + relativeTempAllocatedTimeInMs)
},
tx
);
privilegeId = privilege.id;
privilegeIdToSet = privilege.id;
}
await accessApprovalRequestDAL.updateById(accessApprovalRequest.id, { privilegeId }, tx);
await accessApprovalRequestDAL.updateById(accessApprovalRequest.id, { privilegeId: privilegeIdToSet }, tx);
}
return newReview;
}
throw new BadRequestError({ message: "You have already reviewed this request" });
// Send notification if this was a breakglass approval
if (isBreakGlassApprovalAttempt) {
const cfg = getConfig();
const actingUser = await userDAL.findById(actorId, tx);
if (actingUser) {
const policyApproverUserIds = policy.approvers
.map((ap) => ap.userId)
.filter((id): id is string => typeof id === "string");
if (policyApproverUserIds.length > 0) {
const approverUsersForEmail = await userDAL.find({ $in: { id: policyApproverUserIds } }, { tx });
const recipientEmails = approverUsersForEmail
.map((appUser) => appUser.email)
.filter((email): email is string => !!email);
if (recipientEmails.length > 0) {
await smtpService.sendMail({
recipients: recipientEmails,
subjectLine: "Infisical Secret Access Policy Bypassed",
substitutions: {
projectName: project.name,
requesterFullName: `${actingUser.firstName} ${actingUser.lastName}`,
requesterEmail: actingUser.email,
bypassReason: bypassReason || "No reason provided",
secretPath: policy.secretPath || "/",
environment,
approvalUrl: `${cfg.SITE_URL}/secret-manager/${project.id}/approval`,
requestType: "access"
},
template: SmtpTemplates.AccessSecretRequestBypassed
});
}
}
}
}
return reviewForThisActorProcessing;
});
return reviewStatus;

View File

@ -17,6 +17,8 @@ export type TGetAccessRequestCountDTO = {
export type TReviewAccessRequestDTO = {
requestId: string;
status: ApprovalStatus;
envName?: string;
bypassReason?: string;
} & Omit<TProjectPermission, "projectId">;
export type TCreateAccessApprovalRequestDTO = {

Some files were not shown because too many files have changed in this diff Show More