Compare commits

..

788 Commits

Author SHA1 Message Date
ArshBallagan
b12fe66871 Merge branch 'main' into docs/update-net-sdk 2025-05-29 08:07:43 -07:00
ArshBallagan
28582d9134 Update .NET docs with new links 2025-05-29 08:07:07 -07:00
Maidul Islam
04908edb5b update 2025-05-29 10:28:35 -04:00
Maidul Islam
e8753a3ce8 Update 2025-05-29 10:16:59 -04:00
Sheen
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
Sheen
c22e616771 misc: addressed k8 doc changes 2025-05-29 13:34:41 +00:00
Sheen Capadngan
40711ac707 misc: addressed comments 2025-05-29 21:15:53 +08:00
Daniel Hougaard
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
Daniel Hougaard
78c4a591a9 requested changes 2025-05-29 16:57:22 +04:00
Daniel Hougaard
f6b7717517 fix: allow https on gateway k8s hosts 2025-05-29 16:39:47 +04:00
x032205
b21a5b6425 Merge pull request #3672 from Infisical/ENG-2843
Improved Key Schema docs + tooltip
2025-05-28 23:39:01 -04:00
Maidul Islam
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
Maidul Islam
6bdf62d453 Revert "feat(PIT): Point In Time Revamp" 2025-05-28 20:56:04 -04:00
Maidul Islam
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
Maidul Islam
3148c54e18 Revert "PIT: fix checkpoint creation to do it in batches to avoid insert fails" 2025-05-28 20:55:46 -04:00
x032205
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
x032205
f4e3d7d576 Review fix 2025-05-28 19:22:46 -04:00
x032205
8298f9974f Improved Key Schema docs + tooltip 2025-05-28 19:18:09 -04:00
carlosmonastyrski
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
carlosmonastyrski
5df96234a0 PIT: fix checkpoint creation to do it in batches to avoid insert fails 2025-05-28 20:10:12 -03:00
Maidul Islam
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
carlosmonastyrski
1602fac5ca PIT: decrese PIT_CHECKPOINT_WINDOW to 1 for deployment 2025-05-28 19:16:19 -03:00
carlosmonastyrski
0100bf7032 PIT: decrese PIT_CHECKPOINT_WINDOW to 5 for deployment 2025-05-28 19:13:28 -03:00
Maidul Islam
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
Maidul Islam
e74117b7fd add link to secret zero section 2025-05-28 17:32:03 -04:00
x032205
335aada941 Doc and review tweaks 2025-05-28 17:28:34 -04:00
x032205
b949fe06c3 Doc update 2025-05-28 17:25:21 -04:00
carlosmonastyrski
28e539c481 PIT: improve wording on the revert button 2025-05-28 17:37:44 -03:00
x032205
5c4c881b60 Docs update 2025-05-28 15:50:46 -04:00
x032205
8ffb92bfb3 Docs revamp 2025-05-28 15:39:44 -04:00
Sheen Capadngan
db9a1726c2 misc: doc improvments 2025-05-29 03:32:19 +08:00
carlosmonastyrski
15986633c7 PIT: omit commit version check on rollbacks and reverts 2025-05-28 16:07:42 -03:00
carlosmonastyrski
c4809bbb54 PIT: remove reminders from commit history 2025-05-28 15:51:51 -03:00
x032205
6305aab0d1 Merge branch 'main' into ENG-2827 2025-05-28 14:44:51 -04:00
x032205
456493ff5a feat(secret-sharing): Require Login for Email Sharing 2025-05-28 14:44:27 -04:00
Sheen Capadngan
8cfaefcec5 misc: added missing types 2025-05-29 02:43:36 +08:00
Sheen Capadngan
e39e80a0e7 misc: added proper propagation of error to logs 2025-05-29 02:38:14 +08:00
Sheen Capadngan
8cae92f29e misc: make it work with gateway 2025-05-29 02:01:17 +08:00
Sheen Capadngan
918911f2e4 misc: addressed greptile 2025-05-29 01:40:12 +08:00
Sheen
a1aee45eb2 doc: added docs 2025-05-28 17:36:47 +00:00
Maidul Islam
5fe93dc35a Merge pull request #3669 from Infisical/update-oidc-logs
Update OIDC logs
2025-05-28 12:34:36 -04:00
Scott Wilson
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
Maidul Islam
f663d1d4a6 update log 2025-05-28 12:28:33 -04:00
Sheen Capadngan
650f6d9585 feat: add kubernetes dynamic secret 2025-05-29 00:16:01 +08:00
Maidul Islam
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
carlosmonastyrski
48619ed24c Fix lint issue 2025-05-28 08:50:40 -03:00
carlosmonastyrski
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
carlosmonastyrski
f03a7cc249 PIT: add description to folder versioning 2025-05-28 08:43:32 -03:00
Sheen Capadngan
f2dcbfa91c misc: moved prompt to tooltip 2025-05-28 16:33:14 +08:00
Sheen Capadngan
d08510ebe4 misc: add proper grace period for max ttl and descriptive comment 2025-05-28 16:24:23 +08:00
Sheen
767159bf8f doc: added mention of periodic token to ua section 2025-05-28 08:10:27 +00:00
Sheen Capadngan
98457cdb34 misc: addressed frontend lint 2025-05-28 15:40:09 +08:00
Sheen Capadngan
8ed8f1200d feat: add token period support for ua 2025-05-28 15:35:10 +08:00
Maidul Islam
30252c2bcb minor text updates 2025-05-28 00:06:50 -04:00
Maidul Islam
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
Maidul Islam
a5282a56c9 allow machine identity to read billing 2025-05-27 22:26:32 -04:00
Scott Wilson
cc3551c417 fix: update aws secret manager sync to handle constrained iam policies 2025-05-27 18:25:20 -07:00
Maidul Islam
9e6fe39609 Merge pull request #3663 from Infisical/add-logs-for-oidc-claims
add oidc logs
2025-05-27 21:24:38 -04:00
Maidul Islam
2bc91c42a7 add oidc logs 2025-05-27 21:18:22 -04:00
carlosmonastyrski
c7ec825830 Improve restore buttons on the UI and reconstruct folder children on revert by default 2025-05-27 19:42:31 -03:00
carlosmonastyrski
5b7f445e33 PIT: fix for folder commit order on cascade deletion 2025-05-27 18:28:00 -03:00
carlosmonastyrski
7fe53ab00e PIT: add batch logic to initializeFolder migration 2025-05-27 11:58:17 -03:00
Sheen Capadngan
90c17820fc misc: added proper notice for non-admins doing privilege upgrade 2025-05-27 22:54:50 +08:00
Maidul Islam
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
carlosmonastyrski
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
carlosmonastyrski
8168b5faf8 PIT: fix resourceChangeSchema schema 2025-05-26 23:25:05 -03:00
carlosmonastyrski
8b9e035bf6 PIT: fix folder update issue 2025-05-26 23:08:01 -03:00
carlosmonastyrski
d36d0784ca PIT: Add delete commit for cascade deletion 2025-05-26 21:51:43 -03:00
Maidul Islam
e69354b546 Merge pull request #3640 from akhilmhdh/feat/redis-sentinel-support
Feat/redis sentinel support
2025-05-26 18:47:15 -04:00
Maidul Islam
64bd5ddcc8 Merge branch 'main' into feat/redis-sentinel-support 2025-05-26 18:42:12 -04:00
Maidul Islam
72088634d8 update config file 2025-05-26 18:40:31 -04:00
carlosmonastyrski
f3a84f6001 Merge branch 'main' into feat/point-in-time-revamp 2025-05-26 17:28:38 -03:00
carlosmonastyrski
13672481a8 Merge branch 'main' into feat/point-in-time-revamp 2025-05-26 17:14:30 -03:00
Sheen
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
carlosmonastyrski
c623c615a1 Fix lint issue 2025-05-26 14:52:04 -03:00
carlosmonastyrski
034a8112b7 Merge branch 'main' into feat/point-in-time-revamp 2025-05-26 14:42:55 -03:00
carlosmonastyrski
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
x032205
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
Maidul Islam
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
x032205
1147f87eed lint fixes 2025-05-26 10:56:53 -04:00
x032205
995e3254ba comment fix 2025-05-26 10:41:21 -04:00
x032205
67d0c53912 Merge 2025-05-26 10:39:51 -04:00
Maidul Islam
a6fbcb3e01 Merge pull request #3654 from Infisical/approvals-redesign
improve change requests design
2025-05-26 10:35:47 -04:00
x032205
db1ca2b89f Merge pull request #3643 from Infisical/ENG-2801
feat(policies): Approval Request Break-Glass Bypass
2025-05-26 10:29:21 -04:00
Sheen Capadngan
f91bbe1f31 Merge remote-tracking branch 'origin/main' into feat/acme-and-external-ca 2025-05-26 21:33:23 +08:00
carlosmonastyrski
e5f475e8d6 Fix type and lint issues 2025-05-26 09:16:10 -03:00
carlosmonastyrski
1e4ca2f48f Fix CLI custom headers doc tip 2025-05-26 08:50:28 -03:00
Vladyslav Matsiiako
8d5e7406c3 improve change requests design 2025-05-25 15:53:30 -07:00
Maidul Islam
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
carlosmonastyrski
e5bc609a2a PIT: add last commit indicator and remove unnecessary empty folder commit 2025-05-25 12:07:00 -03:00
carlosmonastyrski
b812761bdd PIT: hide restore button for last commit 2025-05-25 11:52:28 -03:00
carlosmonastyrski
14362dbe6a PIT: general improvements and fixes 2025-05-25 11:00:06 -03:00
carlosmonastyrski
b7b90aea33 PIT: general improvements and fixes 2025-05-25 00:12:31 -03:00
x032205
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
Maidul Islam
eb4e727922 Update overview.mdx 2025-05-24 01:29:38 -04:00
x032205
bb276a0dba review fixes 2025-05-24 01:25:49 -04:00
x032205
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
x032205
ce446fa723 Small out-of-scope greptile fixes 2025-05-23 20:29:34 -04:00
x032205
82f6c9fb58 UI tweaks 2025-05-23 20:18:05 -04:00
x032205
6369d13862 Update docs and some UI to make Admin SSO bypass more clear 2025-05-23 18:47:33 -04:00
Maidul Islam
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
Scott Wilson
c7398d924a improvement: make log more cloudwatch friendly 2025-05-23 15:01:09 -07:00
x032205
df57364985 ui fix 2025-05-23 17:59:29 -04:00
Scott Wilson
84322f4f68 temp: add log to help debug verify loop 2025-05-23 14:10:04 -07:00
x032205
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
x032205
73c6c076e8 Review fixes 2025-05-23 13:18:56 -04:00
x032205
ba2a772247 Merge branch 'main' into ENG-2797 2025-05-23 13:13:43 -04:00
x032205
8fbe46256b Merge pull request #3649 from Infisical/ENG-2820
feat(smtp-service): Custom CA Certs
2025-05-23 13:10:03 -04:00
x032205
b75bb93d83 Describe fix 2025-05-23 13:08:15 -04:00
x032205
db4db04ba6 Doc updates 2025-05-23 13:02:04 -04:00
x032205
db44d958d3 Base64 example for docs 2025-05-23 12:41:58 -04:00
x032205
12beb06682 Swap to using base64 2025-05-23 12:33:31 -04:00
x032205
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
x032205
e81991c545 Merge branch 'main' into ENG-2801 2025-05-23 11:18:45 -04:00
carlosmonastyrski
28a3bf0b94 Improvement on createCommit function to add changes in batches 2025-05-23 10:59:05 -03:00
carlosmonastyrski
5712c24370 Fix migration to initialize pit projects 2025-05-23 10:45:39 -03:00
x032205
65bc522ae9 feat(smtp-service): Custom CA Certs 2025-05-23 03:19:45 -04:00
x032205
b950e07ad6 fixed firefox bug 2025-05-23 02:06:05 -04:00
x032205
498bf8244c Merge branch 'main' into ENG-2807 2025-05-23 01:51:06 -04:00
carlosmonastyrski
4a391c7ac2 PIT: add commits to snapshots and improve old role hidding 2025-05-23 01:46:13 -03:00
x032205
d49c1e4b72 greptile review fixes 2025-05-22 20:41:35 -04:00
Maidul Islam
424e4670e5 Merge pull request #3646 from akhilmhdh/feat/org-id-logger
feat: org id logger
2025-05-22 17:11:21 -07:00
x032205
5e803e76d7 lint 2025-05-22 20:00:02 -04:00
x032205
6648397a64 docs 2025-05-22 19:57:15 -04:00
Maidul Islam
85edbbcdc3 add org id to missing auth modes 2025-05-22 16:29:40 -07:00
x032205
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
Sheen
95ef113aea doc: updated subscriber and external ca 2025-05-22 19:45:34 +00:00
Sheen
07bf65b1c3 doc: add external CA doc with reference to Acme CA 2025-05-22 19:28:21 +00:00
Sheen Capadngan
12071e4816 misc: updated renewal unit UI 2025-05-23 02:51:09 +08:00
Sheen Capadngan
a40d4efa39 misc: updated repeat schedule for auto renewal 2025-05-23 01:28:53 +08:00
x032205
6d509d85f4 feat(app-connections): 1Password App Connection 2025-05-22 13:13:47 -04:00
Sheen Capadngan
5b200f42a3 misc: update audit logs 2025-05-23 01:01:14 +08:00
Sheen Capadngan
64f724ed95 feat: added subscriber cert auto-renewal 2025-05-23 00:53:50 +08:00
x032205
b0d5be6221 Merge pull request #3637 from Infisical/ENG-2803
feat(frontend): Persist "perPage" for tables
2025-05-22 12:38:52 -04:00
carlosmonastyrski
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
x032205
f0a45fb7d8 Review fixes 2025-05-22 11:32:49 -04:00
x032205
40398efb06 Merge branch 'main' into ENG-2803 2025-05-22 11:19:29 -04:00
carlosmonastyrski
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
carlosmonastyrski
ef4df9691d Fix license-fns test changes 2025-05-22 11:46:43 -03:00
carlosmonastyrski
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
Sheen Capadngan
e8d00161eb misc: addressed lint 2025-05-22 21:48:03 +08:00
Sheen Capadngan
0a5a073db1 Merge remote-tracking branch 'origin/main' into feat/acme-and-external-ca 2025-05-22 21:35:20 +08:00
Sheen
0f14685d54 misc: updated doc title 2025-05-22 13:33:15 +00:00
Sheen
d5888d5bbb misc: updated docs based on review 2025-05-22 13:31:00 +00:00
Sheen Capadngan
8ff95aedd5 misc: addressed CA status issue 2025-05-22 20:04:21 +08:00
carlosmonastyrski
2b948a18f3 Type fixes and PIT history pagination 2025-05-21 23:43:41 -03:00
x032205
4d173ad163 ui and backend improvements 2025-05-21 19:46:47 -04:00
x032205
7041b88b9d license revert 2025-05-21 18:44:08 -04:00
carlosmonastyrski
f06004370d PIT: address PR suggestions 2025-05-21 19:42:09 -03:00
x032205
c1fa344f02 Greptile review fixes 2025-05-21 18:17:01 -04:00
Sheen Capadngan
df75b3b8d3 misc: migrated internal CA to use new CA endpoint 2025-05-22 04:21:54 +08:00
Maidul Islam
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
x032205
e3725dd3ab merge + final tweaks 2025-05-21 15:46:36 -04:00
x032205
dc6a94ccda Merge branch 'main' into ENG-2801 2025-05-21 15:02:21 -04:00
x032205
e5229a5377 access request bypass 2025-05-21 15:01:54 -04:00
x032205
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
Sheen Capadngan
d185dbb7ff misc: add proper error message for bypass failure 2025-05-22 01:00:13 +08:00
Sheen Capadngan
77de085ffc misc: addressed first set of review comments 2025-05-22 00:22:49 +08:00
Maidul Islam
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
carlosmonastyrski
2493bbbc97 PIT: fix blocker for deep rollbacks 2025-05-21 09:08:12 -03:00
Sheen Capadngan
77b42836e7 Merge remote-tracking branch 'origin/main' into feat/acme-and-external-ca 2025-05-21 19:21:12 +08:00
Sheen Capadngan
949615606f misc: moved external pki migration to latest along with column changes 2025-05-21 19:07:20 +08:00
x032205
6cd7657e41 lint 2025-05-21 02:44:16 -04:00
x032205
38bf5e8b1d increase name sizes 2025-05-21 02:36:10 -04:00
Maidul Islam
4292cb2a04 Merge pull request #3518 from akhilmhdh/fix/email-ambigious
fix: email casing conflicts
2025-05-20 21:16:16 -07:00
Maidul Islam
051f53c66e Update bug-bounty.mdx 2025-05-20 18:15:36 -07:00
x032205
a6bafb8adc feat(frontend): Persisnt "perPage" for tables 2025-05-20 19:42:32 -04:00
Maidul Islam
99daa43fc6 delete duplicate accounts 2025-05-20 16:40:21 -07:00
x032205
e9e1f4ff5d final touches 2025-05-20 16:53:58 -04:00
x032205
13afc9c996 Merge branch 'main' into ENG-2797 2025-05-20 16:48:28 -04:00
x032205
67d4da40ec review fixes 2025-05-20 16:48:24 -04:00
Scott Wilson
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
Daniel Hougaard
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
DanielHougaard
280fbdfbb9 Update Helm chart to version v0.9.3 2025-05-20 19:54:55 +00:00
Daniel Hougaard
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
Scott Wilson
b20e04bdeb improvements: address feedback 2025-05-20 12:41:37 -07:00
Daniel Hougaard
10d14edc20 Update infisicalpushsecret_controller.go 2025-05-20 23:35:43 +04:00
Maidul Islam
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
Daniel Hougaard
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
x032205
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
x032205
1efdb31037 app connection + finishing touches 2025-05-20 13:25:15 -04:00
Daniel Hougaard
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
carlosmonastyrski
44aa743d56 Type fixes 2025-05-20 11:09:25 -03:00
carlosmonastyrski
fefb71dd86 Merge branch 'main' into feat/point-in-time-revamp 2025-05-20 10:52:20 -03:00
Daniel Hougaard
677180548b Update auth-password-service.ts 2025-05-20 17:47:47 +04:00
carlosmonastyrski
1748052cb0 Merge branch 'main' into feat/point-in-time-revamp 2025-05-20 10:37:41 -03:00
Daniel Hougaard
293bea474e Merge pull request #3626 from Infisical/daniel/agent-injector-docs
docs: k8s agent injector
2025-05-20 17:33:15 +04:00
Daniel Hougaard
bc4fc9a1ca docs: injector diagram 2025-05-20 17:20:54 +04:00
Daniel Hougaard
483850441d Update kubernetes-injector.mdx 2025-05-20 16:58:19 +04:00
Daniel Hougaard
4355fd09cc requested changes 2025-05-20 16:57:11 +04:00
Sheen
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
carlosmonastyrski
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
carlosmonastyrski
9ea9f90928 PIT: add envID to rollback endpoint 2025-05-20 09:34:43 -03:00
carlosmonastyrski
6319f53802 PIT: UI views 2025-05-20 08:22:14 -03:00
Daniel Hougaard
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
Daniel Hougaard
074446df1f Update agent.go 2025-05-20 14:32:07 +04:00
Daniel Hougaard
7ffa0ef8f5 Update deployment.yaml 2025-05-20 12:36:14 +04:00
Daniel Hougaard
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
Sheen
2deaa4eff3 misc: final revisions 2025-05-20 06:14:15 +00:00
Maidul Islam
0b6bc4c1f0 update spend 2025-05-19 21:58:19 -07:00
x032205
966294bd0e move OCI Vault Secret Sync to EE 2025-05-19 23:33:58 -04:00
x032205
e1dee0678e lint fix 2025-05-19 21:42:25 -04:00
x032205
8b25f202fe feat(policies): Specific permission for bypassing policy 2025-05-19 21:28:18 -04:00
Maidul Islam
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
Maidul Islam
565340dc50 fix lint 2025-05-19 18:13:45 -07:00
Maidul Islam
36c428f152 allow hyphens in host name 2025-05-19 17:45:12 -07:00
Maidul Islam
f97826ea82 allow hyphens in host name 2025-05-19 17:42:42 -07:00
Maidul Islam
0f5cbf055c remove limit 2025-05-19 17:27:47 -07:00
Daniel Hougaard
1345ff02e3 docs: k8s agent injector 2025-05-20 01:54:17 +04:00
x032205
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
x032205
0b98a214a7 ui tweaks 2025-05-19 17:15:42 -04:00
x032205
599c2226e4 Merge pull request #3615 from Infisical/ENG-2787
feat(org): Shared Secret limits for org
2025-05-19 16:26:10 -04:00
Sheen
8e24a4d3f8 misc: added docs 2025-05-19 20:19:39 +00:00
x032205
27486e7600 Merge pull request #3625 from Infisical/ENG-2795
fix secret rollback not tainting form
2025-05-19 16:17:26 -04:00
x032205
979e9efbcb fix lint issue 2025-05-19 15:52:50 -04:00
Sheen Capadngan
e06b5ecd1b misc: add error handling for already initialized error 2025-05-20 03:44:21 +08:00
x032205
1097ec64b2 ui improvements 2025-05-19 15:40:07 -04:00
x032205
93fe9929b7 fix secret rollback not tainting form 2025-05-19 15:22:24 -04:00
x032205
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
x032205
b5cf237a4a add product select to docs + change the heading 2025-05-19 13:35:35 -04:00
x032205
6efb630200 Moved secret share limits to secret share settings 2025-05-19 12:32:22 -04:00
x032205
151ede6cbf Merge 2025-05-19 12:20:02 -04:00
x032205
931ee1e8da Merge pull request #3616 from Infisical/ENG-2783
feat(secret-sharing): Specify Emails
2025-05-19 12:12:07 -04:00
x032205
0401793d38 Changed "token" param to "hash" and used hex encoding for URL 2025-05-19 10:48:58 -04:00
Sheen Capadngan
eb31318d39 misc: corrected direct issuance checks for CAs 2025-05-19 21:06:13 +08:00
Sheen Capadngan
7f6dcd3afa Merge remote-tracking branch 'origin/main' into feat/acme-and-external-ca 2025-05-19 20:11:48 +08:00
Sheen Capadngan
2b4a6ad907 misc: addressed review comments 2025-05-19 20:08:43 +08:00
x032205
0613c12508 Merge pull request #3618 from Infisical/fix-bundle-for-old-certs 2025-05-18 13:29:31 -04:00
Sheen Capadngan
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
Sheen Capadngan
c2df8cf869 misc: allow wildcard support for SAN 2025-05-18 23:57:17 +08:00
Sheen
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
Sheen
490c589a44 misc: updated doc reference urls 2025-05-18 15:40:20 +00:00
Sheen Capadngan
b358f2dbb7 feat: added subscriber endpoint for fetching active cert 2025-05-18 23:37:23 +08:00
Sheen Capadngan
10ed6f6b52 misc: finalized descriptions and api reference 2025-05-18 22:22:00 +08:00
Sheen
e0f1311f6d doc: added docs for external CA 2025-05-18 13:31:36 +00:00
Daniel Hougaard
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
Daniel Hougaard
5e192539a1 Update identity-kubernetes-auth-service.ts 2025-05-17 22:13:49 +04:00
Daniel Hougaard
021a8ddace Update identity-kubernetes-auth-service.ts 2025-05-17 22:06:51 +04:00
x032205
f92aba14cd Merge pull request #3619 from Infisical/fix-padding
Org Products Padding Fix
2025-05-17 13:11:56 -04:00
x032205
fdeefcdfcf padding to match similar container 2025-05-17 13:10:15 -04:00
x032205
645f70f770 tweaks 2025-05-17 13:05:09 -04:00
x032205
923feb81f3 fix bundle endpoint for old certs 2025-05-17 12:44:05 -04:00
Sheen Capadngan
1cff92d000 misc: added type assertion 2025-05-18 00:41:27 +08:00
Sheen Capadngan
db8f43385d misc: addressed undefined issue 2025-05-18 00:27:52 +08:00
Sheen Capadngan
41b45c212d misc: addressed lint issue 2025-05-18 00:17:38 +08:00
Sheen Capadngan
ef9269fe10 misc: addressed type issue with date fields 2025-05-18 00:07:03 +08:00
Sheen Capadngan
4d95052896 misc: add indicators for errors 2025-05-17 23:52:20 +08:00
Sheen Capadngan
260679b01d misc: addressed type 2025-05-17 22:39:43 +08:00
x032205
a77cc77be8 explicitly pass values 2025-05-17 03:15:22 -04:00
x032205
9bc5c55cd0 revert license 2025-05-17 03:03:44 -04:00
x032205
2cbad206b5 feat(audit-logs): Audit org updates, project create / update / delete 2025-05-17 03:02:33 -04:00
x032205
16c51af340 review fixes 2025-05-17 02:17:41 -04:00
x032205
9fd37ca456 greptile review fixes 2025-05-17 01:51:05 -04:00
Sheen Capadngan
56b7328231 misc: addressed type issue and ux improvements 2025-05-17 13:00:04 +08:00
x032205
92bebf7d84 feat(secret-sharing): Specify Emails 2025-05-17 00:54:40 -04:00
x032205
df053bbae9 Merge pull request #3611 from Infisical/ENG-2782
feat(project): Enable / Disable Secret Sharing
2025-05-16 18:58:39 -04:00
x032205
42319f01a7 greptile review fixes 2025-05-16 18:54:57 -04:00
x032205
0ea9f9b60d feat(org): Shared Secret limits for org 2025-05-16 18:36:02 -04:00
Scott Wilson
33ce783fda improvements: address feedback 2025-05-16 15:16:36 -07:00
Scott Wilson
63c48dc095 feature: add suport for target principal self rotation 2025-05-16 13:15:33 -07:00
Sheen Capadngan
edefa7698c misc: addressed comments 2025-05-17 03:42:49 +08:00
Scott Wilson
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
Daniel Hougaard
b984111a73 Merge pull request #3612 from Infisical/daniel/cli-auth-fix
fix(auth): cli auth bug
2025-05-16 17:29:21 +04:00
Daniel Hougaard
677ff62b5c fix(auth): cli auth bug 2025-05-16 17:22:18 +04:00
Sheen Capadngan
60ea4bb579 Merge branch 'ENG-2661' into feat/acme-and-external-ca 2025-05-16 21:01:32 +08:00
Daniel Hougaard
8cc2e08f24 fix(auth): cli auth bug 2025-05-16 16:58:01 +04:00
Sheen Capadngan
04d553f052 misc: moved cert issuance to job 2025-05-16 20:38:08 +08:00
Maidul Islam
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
x032205
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
x032205
8e43d2a994 feat(project): Enable / Disable Secret Sharing 2025-05-16 00:08:55 -04:00
x032205
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
Scott Wilson
ef70de1e0b fix: add noopenner to doc link 2025-05-15 20:05:56 -07:00
Scott Wilson
7e9ee7b5e3 fix: add empty display for sso general tab if no sso is enabled 2025-05-15 20:01:08 -07:00
x032205
517c613d05 migration fix 2025-05-15 22:50:09 -04:00
x032205
ae8cf06ec6 greptile review fixes 2025-05-15 21:05:39 -04:00
x032205
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
x032205
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
x032205
e678c9d1cf remove comments 2025-05-15 20:49:01 -04:00
x032205
da0b07ce2a added the other two products and small UI tweaks 2025-05-15 20:45:32 -04:00
x032205
3306a9ca69 Merge pull request #3608 from Infisical/key-schema-tweak
allow underscores in key schema
2025-05-15 18:55:45 -04:00
Maidul Islam
e9af34a6ba Merge pull request #3607 from Infisical/key-schema-doc-tweaks
feat(docs): Key Schema Tweaks
2025-05-15 15:51:23 -07:00
x032205
3de8ed169f allow underscores in key schema 2025-05-15 18:49:30 -04:00
Scott Wilson
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
Scott Wilson
0c1ccf7c2e fix: update oidc group claims to handle single group string 2025-05-15 14:39:07 -07:00
x032205
d268f52a1c small ui tweak 2025-05-15 16:50:37 -04:00
x032205
c519cee5d1 frontend 2025-05-15 16:32:57 -04:00
Sheen Capadngan
6d10afc9d2 feat: POC for ACME done 2025-05-16 02:58:05 +08:00
Maidul Islam
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
Sheen
7b880f85cc misc: add identity support for audit log retention 2025-05-15 16:19:47 +00:00
x032205
c7dc595e1a doc overview update 2025-05-15 12:05:06 -04:00
x032205
6e494f198b Merge pull request #3603 from Infisical/fix-oci-machine-identity
fix oci machine identity
2025-05-15 11:42:58 -04:00
x032205
e1f3eaf1a0 Comment for regex 2025-05-15 11:41:00 -04:00
Daniel Hougaard
be26dc9872 requested changes 2025-05-15 16:55:36 +04:00
Daniel Hougaard
aaeb6e73fe requested changes 2025-05-15 16:06:20 +04:00
x032205
1e11702c58 remove unused import 2025-05-15 01:17:38 -04:00
x032205
3b81cdb16e fix oci machine identity 2025-05-15 01:12:33 -04:00
x032205
6584166815 Merge pull request #3598 from Infisical/ENG-2755
feat(secret-sync): Secret Key Schema
2025-05-14 23:57:18 -04:00
x032205
827cb35194 review fixes 2025-05-14 23:52:05 -04:00
Maidul Islam
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
Scott Wilson
3b9a50d65d improvements: address feedback 2025-05-14 16:20:50 -07:00
Scott Wilson
beb7200233 fix: correct overview image links 2025-05-14 14:29:46 -07:00
Scott Wilson
18e3d132a2 documentation: add general oidc group membership mapping documentation 2025-05-14 14:22:35 -07:00
Sheen Capadngan
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
x032205
3f74d3a80d update import 2025-05-14 13:49:25 -04:00
x032205
4a44dc6119 format a frontend file 2025-05-14 13:45:45 -04:00
x032205
dd4bc4bc73 more doc tweaks 2025-05-14 13:43:23 -04:00
x032205
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
Daniel Hougaard
36310387e0 Update oci-auth.mdx 2025-05-14 20:44:41 +04:00
x032205
43f3960225 Merge branch 'main' into ENG-2706 2025-05-14 12:35:17 -04:00
Scott Wilson
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
Scott Wilson
7e05bc86a9 improvement: address feedback 2025-05-14 08:58:29 -07:00
x032205
b0c4fddf86 review fixes 2025-05-14 11:23:12 -04:00
Sheen Capadngan
6faad102e2 misc: added internal CA route 2025-05-14 23:10:10 +08:00
Maidul Islam
f5578d39a6 Merge pull request #3597 from Infisical/linux-upgrade-docs
add linux upgrade docs
2025-05-14 07:45:01 -07:00
carlosmonastyrski
8bfd3913da PIT: add backend logic for deep PIT and rollback 2025-05-14 10:26:41 -03:00
Daniel Hougaard
cd028ae133 Update 20250212191958_create-gateway.ts 2025-05-14 16:01:07 +04:00
Daniel Hougaard
63c71fabcd fix: migrate project gateway 2025-05-14 16:00:27 +04:00
Daniel Hougaard
e90166f1f0 Merge branch 'heads/main' into daniel/k8s-auth-gateway 2025-05-14 14:26:05 +04:00
Sheen Capadngan
d1e5ae2d85 misc: updated pki collection lst 2025-05-14 14:45:24 +08:00
Sheen
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
Sheen Capadngan
7c52e000cd misc: update custom cert to be crt format for docs 2025-05-14 14:12:08 +08:00
x032205
cccd4ba9e5 doc changes and other tweaks 2025-05-14 01:32:09 -04:00
x032205
63f0f8e299 final release 2025-05-14 01:16:42 -04:00
Maidul Islam
c8a3837432 refine docs 2025-05-13 22:02:49 -07:00
Vlad Matsiiako
2dd407b136 Merge pull request #3596 from Infisical/pulumi-documentation-update
Adding Pulumi documentation
2025-05-13 22:21:33 -06:00
Maidul Islam
4e1a5565d8 add linux upgrade docs 2025-05-13 20:40:29 -07:00
x032205
bae62421ae with stripSchema and filterForSchema 2025-05-13 23:08:54 -04:00
ArshBallagan
d397002704 Update pulumi.mdx 2025-05-13 20:29:06 -06:00
ArshBallagan
f5b1f671e3 Update pulumi.mdx 2025-05-13 20:17:23 -06:00
ArshBallagan
0597c5f0c0 Adding Pulumi documentation 2025-05-13 20:14:08 -06:00
Scott Wilson
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
Scott Wilson
b67457fe93 chore: remove unused imports 2025-05-13 18:46:53 -07:00
Scott Wilson
75abdbe938 remove legacy badge/banner from native integrations UI 2025-05-13 18:41:14 -07:00
x032205
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
x032205
13b2f65b7e lint fix 2025-05-13 16:51:05 -04:00
x032205
6cf1e046b0 Fixed project roles not being editable in some cases 2025-05-13 16:38:26 -04:00
Sheen Capadngan
e5555ffd3f misc: addressed cert issuance restriction update 2025-05-14 04:20:00 +08:00
Sheen Capadngan
6b95bb0ceb misc: continued migration to new ca structure 2025-05-14 04:08:57 +08:00
Scott Wilson
f6e1441dc0 Merge pull request #3570 from Infisical/policy-templates
feature(project-roles): Project Role Templates
2025-05-13 12:47:40 -07:00
Scott Wilson
7ed96164e5 improvement: address feedback 2025-05-13 12:25:24 -07:00
Scott Wilson
9eeb72ac80 fix: correct import 2025-05-13 12:18:35 -07:00
Scott Wilson
f6e566a028 merge main 2025-05-13 12:10:49 -07:00
x032205
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
x032205
eef7a875a1 Merge pull request #3585 from Infisical/ENG-2748
feat(docs): Self approval
2025-05-13 14:05:59 -04:00
x032205
09938a911b nit fix 2025-05-13 13:58:52 -04:00
x032205
af08c41008 Merge pull request #3567 from Infisical/ENG-2636
feat(secret-sync): OCI Vault
2025-05-13 13:25:11 -04:00
x032205
443c8854ea Merge branch 'main' into ENG-2636 2025-05-13 13:16:59 -04:00
x032205
f7a25e7601 Merge pull request #3592 from Infisical/lint-fix
lint fix
2025-05-13 13:16:06 -04:00
x032205
4c6e5c9c4c lint fix 2025-05-13 13:11:20 -04:00
Maidul Islam
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
Sheen Capadngan
b0e25a8bd1 Merge remote-tracking branch 'origin/main' into feat/acme-and-external-ca 2025-05-14 00:06:40 +08:00
Maidul Islam
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
x032205
d483e70748 review fixes 2025-05-13 10:44:28 -04:00
Daniel Hougaard
8adf4787b9 Update 20250513081738_remove-gateway-project-link.ts 2025-05-13 15:31:13 +04:00
Daniel Hougaard
a12522db55 requested changes 2025-05-13 15:18:23 +04:00
Daniel Hougaard
49ab487dc2 Update organization-permissions.mdx 2025-05-13 15:04:21 +04:00
Daniel Hougaard
daf0731580 feat(gateways): decouple gateways from projects 2025-05-13 14:59:58 +04:00
Sheen Capadngan
4b94848a79 Merge remote-tracking branch 'origin/main' into ENG-2661 2025-05-13 16:35:42 +08:00
Sheen
b5ef2a6837 Merge pull request #3569 from Infisical/pki-subscriber
Infisical PKI: Subscriber Functionality
2025-05-13 16:34:05 +08:00
Sheen Capadngan
879b12002c Merge remote-tracking branch 'origin/main' into ENG-2661 2025-05-13 16:24:55 +08:00
Sheen Capadngan
9c611daada misc: updated org delete flow to clear session 2025-05-13 16:09:26 +08:00
x032205
71edb08942 Merge pull request #3587 from Infisical/ENG-2763
Fix approval request ordering
2025-05-12 23:54:27 -04:00
x032205
89d8261a43 Fix approval request ordering 2025-05-12 23:13:57 -04:00
Scott Wilson
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
Scott Wilson
76864ababa fix: correct doc casing 2025-05-12 18:37:05 -07:00
x032205
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
x032205
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
x032205
c031233247 feat(docs): Self approval 2025-05-12 21:04:05 -04:00
Scott Wilson
d17d40ebd9 improvements: refactor org security settings tab to sso page and update doc images 2025-05-12 17:18:40 -07:00
x032205
70fff1f2da review fixes 2025-05-12 19:38:00 -04:00
x032205
3f8eaa0679 remove schema change 2025-05-12 18:13:14 -04:00
Scott Wilson
50d0035d7b fix: correct remove oci secret if secret value is empty logic 2025-05-12 14:56:13 -07:00
Tuan Dang
9743ad02d5 Fix lint issues 2025-05-12 14:56:00 -07:00
x032205
50f5248e3e Merge branch 'main' into feat/return-metadata-with-identity-create 2025-05-12 17:50:13 -04:00
x032205
8d7b573988 final reviews 2025-05-12 17:39:29 -04:00
Tuan Dang
26d0ab1dc2 Fix lint issues 2025-05-12 14:34:14 -07:00
Sheen Capadngan
bc93db8603 misc: initial setup 2025-05-13 05:02:15 +08:00
x032205
4acdbd24e9 remove useless schema 2025-05-12 16:50:47 -04:00
x032205
c3c907788a review fixes 2025-05-12 16:42:48 -04:00
Tuan Dang
bf833a57cd Fix merge conflicts 2025-05-12 12:59:54 -07:00
Tuan Dang
e8519f6612 Revise PR based on review 2025-05-12 12:56:56 -07:00
x032205
0b4675e7b5 Merge branch 'main' into ENG-2636 2025-05-12 14:56:01 -04:00
x032205
091e521180 review fixes 2025-05-12 14:49:45 -04:00
Daniel Hougaard
07df6803a5 Merge pull request #3581 from Infisical/daniel/unblock-dev
fix: move cli install to aws
2025-05-12 18:54:55 +04:00
x032205
d5dbc7d7e0 erge branch 'daniel/unblock-dev' into ENG-2706 2025-05-12 10:52:40 -04:00
Daniel Hougaard
a09d0e8948 fix: move cli install to aws 2025-05-12 18:47:02 +04:00
x032205
c43a87947f merge fixes 2025-05-12 10:29:52 -04:00
x032205
0af9415aa6 Merge branch 'main' into ENG-2706 2025-05-12 10:18:33 -04:00
Daniel Hougaard
fb2b64cb19 feat(identities/k8s): gateway support 2025-05-12 15:19:42 +04:00
Daniel Hougaard
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
x032205
2793ac22aa remove duplicate field 2025-05-11 22:27:09 -04:00
x032205
31fad03af8 Return metadata with identity post endpoints 2025-05-09 23:41:11 -04:00
x032205
ce612877b8 docs 2025-05-09 22:47:20 -04:00
x032205
4ad8b468d5 Merge branch 'main' into ENG-2706 2025-05-09 22:37:22 -04:00
x032205
5742fc648b add tenancy OCID requirement 2025-05-09 22:33:02 -04:00
carlosmonastyrski
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
Scott Wilson
aa68a3ef58 feature: add org role duplication 2025-05-09 14:29:18 -07:00
Daniel Hougaard
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
Scott Wilson
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
Scott Wilson
8ecb5ca7bc remove extra margin 2025-05-09 13:47:28 -07:00
Daniel Hougaard
ab6a2b7dbb fix(workflow-integrations): microsoft teams scaling issues 2025-05-10 00:47:22 +04:00
carlosmonastyrski
81bfc04e7c Trim hostname input on SSH Host permission form and fix getWorkspaceUsers key invalidation 2025-05-09 17:10:01 -03:00
x032205
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
Scott Wilson
ce8e18f620 improvement: address feedback 2025-05-09 12:40:07 -07:00
Scott Wilson
d09c964647 fix: use tanstack router link 2025-05-09 12:32:37 -07:00
Scott Wilson
eeddbde600 improvement: update org project templates relocation banner 2025-05-09 12:23:05 -07:00
carlosmonastyrski
9e1d38a27b Add PIT rollback 2025-05-09 16:03:50 -03:00
Daniel Hougaard
859b643e43 Delete ssh 2025-05-09 22:49:39 +04:00
Daniel Hougaard
91f71e0ef6 feat(cli): upgrade secret scanner 2025-05-09 22:48:56 +04:00
x032205
4e9e31eeb7 added credit 2025-05-09 13:45:36 -04:00
x032205
f6bc99b964 support openapi titles for zod description 2025-05-09 13:40:15 -04:00
Scott Wilson
679eb9dffc fix: correct project templates empty table display if feature is disabled 2025-05-09 10:14:03 -07:00
x032205
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
x032205
519a0c1bdf Merge branch 'main' into ENG-2692 2025-05-09 11:31:05 -04:00
x032205
e9d8979cf4 add rate limit to all email-sending endpoints 2025-05-09 11:29:53 -04:00
Maidul Islam
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
carlosmonastyrski
aea44088db Merge branch 'main' into feat/addGroupsToSshHosts 2025-05-09 09:21:29 -03:00
carlosmonastyrski
78d5bc823d PIT: Add folder reconstruction functions 2025-05-09 09:20:17 -03:00
x032205
578a0d7d93 review fixes 2025-05-09 02:54:49 -04:00
x032205
cd71db416d cancel deletion + update on creation for scheduled for deletion secrets 2025-05-09 02:34:50 -04:00
x032205
9d682ca874 added RE2 to regex 2025-05-09 02:10:53 -04:00
x032205
9054db80ad truncation and UI tweaks 2025-05-09 02:05:30 -04:00
x032205
5bb8756c67 only list compartments which the user is authorized to 'use vaults' in 2025-05-09 01:49:34 -04:00
x032205
8b7cb4c4eb Merge branch 'main' into ENG-2636 2025-05-09 01:34:19 -04:00
x032205
a6ee6fc4ea docs, grammar fixes, frontend tweak 2025-05-09 01:29:11 -04:00
Daniel Hougaard
e584c9ea95 test 2025-05-09 09:04:30 +04:00
Maidul Islam
428c60880a Update jumpcloud.mdx 2025-05-09 00:28:20 -04:00
Maidul Islam
2179b9a4d7 Update general.mdx 2025-05-09 00:27:43 -04:00
x032205
b21c17572d block local and private IPs on host header 2025-05-09 00:08:02 -04:00
Scott Wilson
44c7be54cf improvement: address feedback 2025-05-08 20:22:42 -07:00
Scott Wilson
45c08b3f09 improvement: improve role not found error display 2025-05-08 20:15:47 -07:00
Scott Wilson
57a29577fe feature: duplicate project role 2025-05-08 20:10:25 -07:00
x032205
2700a96df4 Remove unused package 2025-05-08 21:30:40 -04:00
x032205
7457ef3b66 bug fix 2025-05-08 21:24:03 -04:00
x032205
806df70dd7 tweaks 2025-05-08 21:03:58 -04:00
x032205
8eda358c17 schema gen 2025-05-08 20:59:05 -04:00
x032205
b34aabe72b merges 2025-05-08 20:56:04 -04:00
Daniel Hougaard
1921763fa8 fix: update to upcoming version 2025-05-09 04:43:13 +04:00
x032205
dfaed3c513 oci machine identity auth option 2025-05-08 20:42:58 -04:00
Daniel Hougaard
5408859a18 fix: update gitleaks/go-diff to latest version 2025-05-09 04:40:09 +04:00
Daniel Hougaard
8dfc0cfbe0 Merge pull request #3571 from Infisical/daniel/identities-ldap-docs
docs(identities): ldap auth
2025-05-09 04:15:11 +04:00
Daniel Hougaard
060199e58c fix: machine identities -> identities 2025-05-09 04:13:11 +04:00
Daniel Hougaard
3b9b17f8d5 requested changes 2025-05-09 04:12:21 +04:00
Daniel Hougaard
6addde2650 docs(identities): ldap auth 2025-05-09 03:44:15 +04:00
Scott Wilson
5b7627585f improvements: address feedback 2025-05-08 16:17:25 -07:00
Scott Wilson
800ea5ce78 feature: project role templates 2025-05-08 16:02:41 -07:00
Tuan Dang
a6b3be72a9 Make minor PR adjustments 2025-05-08 14:02:25 -07:00
Daniel Hougaard
394bd6755f Merge pull request #3566 from Infisical/daniel/identity-ldap-auth
feat(identities): ldap auth
2025-05-08 23:53:47 +04:00
Daniel Hougaard
c21873ac4b Update identity-ldap-auth-router.ts 2025-05-08 23:48:08 +04:00
Daniel Hougaard
64b8c1a2de added filter check 2025-05-08 23:44:30 +04:00
Daniel Hougaard
de443c5ea1 fix: requested changes 2025-05-08 23:20:18 +04:00
Daniel Hougaard
a3b7df4e6b fix: addressed requested changes 2025-05-08 23:13:46 +04:00
Tuan Dang
531607dcb7 Revise pr based on greptile review 2025-05-08 10:37:33 -07:00
Tuan Dang
182de009b2 Fix lint issues 2025-05-08 10:01:44 -07:00
Tuan Dang
f1651ce171 Rename migration file 2025-05-08 09:10:49 -07:00
Tuan Dang
e1f563dbd4 Fix merge conflicts 2025-05-08 09:07:28 -07:00
Tuan Dang
107cca0b62 Complete preliminary docs for pki subscribers 2025-05-08 08:52:10 -07:00
x032205
72abc08f04 Merge branch 'main' into ENG-2636 2025-05-08 10:29:52 -04:00
Sheen Capadngan
a4b648ad95 misc: addressed tooltip display issue 2025-05-08 21:24:26 +08:00
carlosmonastyrski
e8d424bbb0 PIT: Add initialization and checkpoint logic 2025-05-08 09:41:01 -03:00
x032205
04a8931cf6 Merge pull request #3568 from Infisical/pki-merge-fix
small migration fix
2025-05-08 01:23:36 -04:00
x032205
ab0b8c0f10 migration tweak 2025-05-08 01:22:34 -04:00
x032205
258836a605 migration tweak 2025-05-08 01:17:47 -04:00
x032205
d6b31cde44 greptile review fixes 2025-05-08 01:16:42 -04:00
x032205
2c94f9ec3c revert eslint memory increase 2025-05-08 00:50:31 -04:00
x032205
42ad63b58d increase max old space size for lint:fix 2025-05-08 00:44:03 -04:00
x032205
f2d5112585 Merge branch 'main' into ENG-2636 2025-05-08 00:27:28 -04:00
x032205
9c7b25de49 docs + tweaks 2025-05-08 00:25:19 -04:00
Daniel Hougaard
0b31d7f860 feat(identities): ldap auth, requested changes 2025-05-08 08:14:29 +04:00
Daniel Hougaard
5c91d380b8 feat(identities): ldap auth 2025-05-08 07:55:22 +04:00
Daniel Hougaard
b908893a68 feat(identities): ldap auth 2025-05-08 07:49:23 +04:00
Maidul Islam
4d0275e589 Merge pull request #3565 from Infisical/remove-migration-folder
Remove unused migration folder
2025-05-07 20:53:51 -04:00
Maidul Islam
6ca7a990f3 unused folder remove 2025-05-07 20:34:01 -04:00
Scott Wilson
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
Daniel Hougaard
1d44774913 Merge pull request #3564 from Infisical/daniel/generator-doc-imp
docs(k8s/generators): improve documentation
2025-05-08 03:20:30 +04:00
Maidul Islam
984552eea9 rephrase generator overview 2025-05-07 19:18:45 -04:00
Scott Wilson
b6a957a30d fix: select all apply to filtered policies only, skip replacing existing policies 2025-05-07 15:34:34 -07:00
x032205
36954a9df9 secret sync + tweaks 2025-05-07 17:57:00 -04:00
Daniel Hougaard
2f4efad8ae Update infisical-push-secret-crd.mdx 2025-05-08 01:47:00 +04:00
Scott Wilson
16c476d78c fix: correct policies typos 2025-05-07 14:09:32 -07:00
Scott Wilson
68c549f1c6 improvement: add select polices modal 2025-05-07 13:50:27 -07:00
Scott Wilson
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
Daniel Hougaard
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
DanielHougaard
7e432a4297 Update Helm chart to version v0.9.2 2025-05-07 18:27:13 +00:00
Scott Wilson
794fc9c2a2 improvements: address feedback 2025-05-07 11:23:51 -07:00
Daniel Hougaard
d4e5d2c7ed Merge pull request #3540 from Infisical/daniel/generators
feat(k8s): generator support
2025-05-07 22:10:22 +04:00
x032205
581840a701 fixed app connection endpoints 2025-05-07 13:53:05 -04:00
Sheen
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
Sheen Capadngan
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
Daniel Hougaard
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
x032205
40e976133c Merge pull request #3528 from Infisical/ENG-2647
feat(admin): Invalidate Cache
2025-05-07 11:50:57 -04:00
x032205
ad2f002822 Merge pull request #3558 from Infisical/pki-docs-patch
docs fix
2025-05-07 11:06:24 -04:00
x032205
8842dfe5d1 docs fix 2025-05-07 11:01:19 -04:00
x032205
326742c2d5 feat(app-connections): OCI 2025-05-07 10:59:27 -04:00
carlosmonastyrski
f0c52cc8da Add comments to provide context on this change 2025-05-07 08:43:56 -03:00
carlosmonastyrski
e58dbe853e Minor improvements on commits code quality 2025-05-07 08:38:19 -03:00
Sheen
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
Sheen Capadngan
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
Daniel Hougaard
c891b8f5d3 fix routing 2025-05-07 03:00:20 +04:00
Tuan Dang
a32bb95703 Start work on PkiSubscriberDetailsByIDPage 2025-05-06 15:46:54 -07:00
x032205
334a05d5f1 fix lint 2025-05-06 18:08:08 -04:00
x032205
12c813928c fix polling 2025-05-06 18:00:24 -04:00
carlosmonastyrski
f493a617b1 Add new commit logic on every folder/secret operation 2025-05-06 18:57:25 -03:00
x032205
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
x032205
3cf5c534ff Merge pull request #3553 from Infisical/pki-docs-patch
patch(docs): mint.json update
2025-05-06 15:54:31 -04:00
Sheen Capadngan
2b03c295f9 feat: adjustments to properties and validation 2025-05-07 03:51:22 +08:00
x032205
4fc7a52941 patch(docs): mint.json update 2025-05-06 15:38:10 -04:00
Scott Wilson
0ded2e51ba fix: filter project templates polices by type 2025-05-06 11:59:59 -07:00
Maidul Islam
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
Maidul Islam
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
Maidul Islam
f9d76aae5d Update bug-bounty.mdx 2025-05-06 14:46:42 -04:00
Daniel Hougaard
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
Scott Wilson
4562f57b54 improvements: refactor project templates, filter policies by project type, project type specific roles 2025-05-06 11:26:09 -07:00
Daniel Hougaard
6005dce44d fix: allow secret scanning from all self-hosted orgs 2025-05-06 22:16:29 +04:00
Tuan Dang
0410c83cef Fix merge conflicts 2025-05-06 09:46:31 -07:00
Tuan Dang
cf4f2ea6b1 Begin developing pki subscriber 2025-05-06 09:44:57 -07:00
carlosmonastyrski
bf85df7e36 Fix SSH table UI user groups issues 2025-05-06 08:37:19 -03:00
carlosmonastyrski
32a3e1d200 commit 2025-05-06 08:11:50 -03:00
Daniel Hougaard
f7f7d2d528 fix: typo 2025-05-06 08:24:59 +04:00
Daniel Hougaard
57342cf2a0 docs: secret scanning self hosted documentation 2025-05-06 08:14:05 +04:00
Maidul Islam
d530604b51 Merge pull request #3547 from Infisical/add-host-to-envar
Add missing HOST environment var
2025-05-05 20:46:20 -04:00
Maidul Islam
229c7c0dcf Add missing HOST environment var
Added missing HOST environment var
2025-05-05 20:43:45 -04:00
Maidul Islam
6a79830e01 Update bug-bounty.mdx 2025-05-05 17:32:18 -04:00
x032205
7447d17e94 bug fix, migration fix, frontend tweak 2025-05-05 17:21:59 -04:00
x032205
4efa4ad8df merging PKI PRs 2025-05-05 17:06:32 -04:00
x032205
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
x032205
86bb2659b5 small ui tweaks 2025-05-05 16:07:04 -04:00
x032205
dc59f226b6 swapped polling to react query 2025-05-05 15:58:45 -04:00
carlosmonastyrski
c6e56f0380 Stop removing secret/folder versions on projects with version >= 3 2025-05-05 16:43:58 -03:00
Scott Wilson
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
x032205
9175c1dffa Merge branch 'main' into ENG-2647 2025-05-05 15:27:25 -04:00
Scott Wilson
210f1dc2a2 fix: revert dev comment out 2025-05-05 12:24:12 -07:00
Scott Wilson
7851bb8710 improvement: address feedback 2025-05-05 12:23:18 -07:00
x032205
f6e802c017 review fixes: docs + frontend 2025-05-05 15:07:57 -04:00
Scott Wilson
d28c87ee67 fix: use dns lookup as fallback for dns resolve 2025-05-05 11:56:49 -07:00
x032205
b6e6a3c6be docs changes 2025-05-05 14:50:54 -04:00
Andrey Lyubavin
54927454bf ui fetch private key if permission allows it 2025-05-05 14:37:20 -04:00
carlosmonastyrski
b9070a8fa3 Merge branch 'main' into feat/addGroupsToSshHosts 2025-05-05 14:51:01 -03:00
Andrey Lyubavin
1ce06891a5 ui tweak for role policies 2025-05-05 13:43:38 -04:00
Andrey Lyubavin
3a8154eddc Merge branch 'main' into ENG-2685 2025-05-05 13:37:43 -04:00
Andrey Lyubavin
d61216ed62 Merge branch 'main' into ENG-2661 2025-05-05 13:33:19 -04:00
Daniel Hougaard
95b6676976 Merge pull request #3539 from Infisical/daniel/gateway-helm-docs
docs(gateway-helm): helm deployment
2025-05-05 17:45:36 +04:00
Maidul Islam
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
Daniel Hougaard
1e4dfd0c7c fix(k8s/generators): update base crds 2025-05-05 02:35:57 +04:00
Daniel Hougaard
34b7d28e2f requested changes 2025-05-05 02:30:59 +04:00
Daniel Hougaard
245a348517 Update generators.go 2025-05-05 02:13:12 +04:00
Daniel Hougaard
e0fc582e2e docs(k8s/generators): docs and minor fix 2025-05-05 02:09:21 +04:00
Daniel Hougaard
68ef897b6a fix: logs and rbac 2025-05-05 01:39:30 +04:00
Daniel Hougaard
1b060e76de Update kustomization.yaml 2025-05-05 01:08:22 +04:00
Daniel Hougaard
9f7599b2a1 feat(k8s): generators 2025-05-05 00:59:11 +04:00
Daniel Hougaard
edd415aed8 Update overview.mdx 2025-05-05 00:40:49 +04:00
Daniel Hougaard
c816cbc9a9 docs(gateway-helm): helm deployment 2025-05-05 00:09:59 +04:00
Daniel Hougaard
416811d594 Merge pull request #3524 from Infisical/daniel/gateway-helm
feat(helm): infisical helm
2025-05-04 23:52:19 +04:00
Maidul Islam
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
Sheen
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
Scott Wilson
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
Maidul Islam
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
BlackMagiq
3757f190f0 Merge pull request #3522 from Infisical/host-groups
Infisical SSH - Add Support for Host Groups
2025-05-02 13:46:02 -07:00
Maidul Islam
fec55bc9f8 fix greptile recs 2025-05-02 16:40:56 -04:00
Tuan Dang
a285a14fff Fix SshHostsTable component 2025-05-02 13:38:21 -07:00
Tuan Dang
9ec7d0d03e Update login mapping rendering on ssh hosts 2025-05-02 13:37:39 -07:00
Tuan Dang
d5246c2891 Update rendering on login mappings on hosts table 2025-05-02 13:30:48 -07:00
Daniel Hougaard
dcb7215b7d requested changes 2025-05-03 00:20:25 +04:00
x032205
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
Tuan Dang
0dcb223f80 Fix merge conflicts 2025-05-02 13:06:18 -07:00
x
877485b45a queue job 2025-05-02 15:23:35 -04:00
Scott Wilson
f9f098af86 fix: try updating tsup.config to account for .tsx 2025-05-02 12:20:17 -07:00
Tuan Dang
6a5748150a Revise PR based on review 2025-05-02 12:16:51 -07:00
Scott Wilson
3ef053f255 fix: test adding explicity .tsx path 2025-05-02 12:13:23 -07:00
carlosmonastyrski
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
Scott Wilson
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
Scott Wilson
717c947e53 fix: try removing jsx usage 2025-05-02 11:42:20 -07:00
Scott Wilson
8ad334b3ab fix: try reverting ts jsx type 2025-05-02 11:34:18 -07:00
Scott Wilson
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
carlosmonastyrski
3ea450e94a Add groups to ssh hosts allowed principals fix delete principal row issue 2025-05-02 13:41:53 -03:00
carlosmonastyrski
7d0574087c Add groups to ssh hosts allowed principals bot improvements 2025-05-02 13:36:05 -03:00
carlosmonastyrski
46755f724c Improve /complete-account/signup body schema 2025-05-02 13:06:45 -03:00
carlosmonastyrski
e12f4ad253 Add cloud check on github add user to default org 2025-05-02 12:58:36 -03:00
carlosmonastyrski
36916704be Add groups to ssh hosts allowed principals 2025-05-02 11:14:43 -03:00
Daniel Hougaard
5dbded60f4 Delete Dockerfile.gateway 2025-05-02 16:38:31 +04:00
Daniel Hougaard
a80d5f10e5 fix(gateway-helm): requested changes 2025-05-02 16:38:02 +04:00
Sheen
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
carlosmonastyrski
365b4b975e Add minor improvements to Github SSO users added to default organization on signup 2025-05-02 08:22:47 -03:00
Sheen
fbf634f7da doc: add mentions of PKCE and eddsa alg for oidc 2025-05-02 07:57:37 +00:00
Maidul Islam
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
x032205
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
x032205
81396f6b51 Small docs change 2025-05-01 20:23:29 -04:00
carlosmonastyrski
63279280fd Add Github SSO users to default organization on signup 2025-05-01 20:41:30 -03:00
Scott Wilson
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
Daniel Hougaard
f2d9593660 Merge pull request #3486 from Infisical/daniel/ms-teams-integration
feat(workflow-integrations): microsoft teams
2025-05-02 00:46:19 +04:00
Daniel Hougaard
219964a242 fix: query invalidation 2025-05-02 00:41:46 +04:00
x
9f1ac77afa invalidate cache 2025-05-01 16:34:29 -04:00
Daniel Hougaard
240f558231 fix: added empty state 2025-05-01 23:49:18 +04:00
Daniel Hougaard
f3b3df1010 Update MicrosoftTeamsIntegrationForm.tsx 2025-05-01 20:43:23 +04:00
Daniel Hougaard
1fd6cd4787 Update MicrosoftTeamsIntegrationForm.tsx 2025-05-01 20:34:09 +04:00
Daniel Hougaard
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
Daniel Hougaard
550cb2b5ec smaller ui improvements 2025-05-01 19:50:50 +04:00
Daniel Hougaard
75cb259c51 add description tooltip 2025-05-01 19:15:29 +04:00
x
be2c5a9e57 merge conflicts 2025-05-01 10:48:33 -04:00
Daniel Hougaard
a077a9d6f2 Update OauthCallbackPage.tsx 2025-05-01 18:27:29 +04:00
x032205
296493484f Merge pull request #3525 from Infisical/ENG-2669
feat(agent): Sync Imported Secrets
2025-05-01 10:14:41 -04:00
Daniel Hougaard
835b2fba9c requested changes 2025-05-01 18:02:27 +04:00
Sheen
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
Sheen Capadngan
a9c1c197f7 misc: added min width 2025-05-01 20:35:29 +08:00
Maidul Islam
5bd7dd4d65 Merge pull request #3521 from Infisical/bug-bounty-program
Add bug bounty program
2025-05-01 08:35:11 -04:00
Sheen Capadngan
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
Daniel Hougaard
82c7dad6c8 feat(helm): infisical helm 2025-05-01 06:45:40 +04:00
Tuan Dang
83df0850ce Fix frontend lint issues 2025-04-30 19:44:56 -07:00
Tuan Dang
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
Tuan Dang
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
Tuan Dang
b21b0b340b Complete preliminary ssh host group feature 2025-04-30 18:14:31 -07:00
Maidul Islam
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
Daniel Hougaard
9e56790886 Update OauthCallbackPage.tsx 2025-05-01 04:13:46 +04:00
Daniel Hougaard
e08c5f265e fix: improve auth step to avoid takeovers 2025-05-01 04:08:58 +04:00
Maidul Islam
e7a55d8a27 Merge pull request #3440 from Infisical/feat/azureClientSecretsRotation
Feat/azure client secrets rotation
2025-04-30 19:45:02 -04:00
carlosmonastyrski
35b8adb0f6 Fix order of Secret Rotation docs 2025-04-30 20:13:20 -03:00
carlosmonastyrski
d161be1170 Improve error propagation and change appId to objectId to match azure 2025-04-30 20:06:13 -03:00
Maidul Islam
aabf933756 Add bug bounty program
Added a formal bounty program
2025-04-30 18:56:23 -04:00
Maidul Islam
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
Daniel Hougaard
69ef7fdf3b Update index.ts 2025-05-01 01:32:45 +04:00
carlosmonastyrski
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
carlosmonastyrski
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
carlosmonastyrski
c99440ba81 feat(user-auth): use ms library and update docs 2025-04-30 16:49:33 -03:00
carlosmonastyrski
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
carlosmonastyrski
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
carlosmonastyrski
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
x032205
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
carlosmonastyrski
98bb5d7aa7 Address PR comments for Azure Client Secret Rotation 2025-04-30 10:11:38 -03:00
carlosmonastyrski
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
Tuan Dang
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
Daniel Hougaard
98f742a807 Merge pull request #3513 from Infisical/daniel/k8s-hsm-docs
docs: fix hsm kubernetes documentation
2025-04-30 06:10:30 +04:00
Daniel Hougaard
66f1967f88 Update hsm-integration.mdx 2025-04-30 05:37:55 +04:00
Daniel Hougaard
da6cf85c8d fix: remove log output file 2025-04-30 05:37:07 +04:00
Daniel Hougaard
e8b6eb0573 docs: fix hsm kubernetes documentation 2025-04-30 05:09:39 +04:00
Maidul Islam
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
Daniel Hougaard
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
carlosmonastyrski
2a28d74bde Address PR comments for Azure Client Secret Rotation 2025-04-29 20:19:30 -03:00
Daniel Hougaard
d4ac4f8d8f Update CollapsibleSecretImports.tsx 2025-04-30 03:13:10 +04:00
Daniel Hougaard
aedc6e16ad Update .infisicalignore 2025-04-30 02:51:48 +04:00
Daniel Hougaard
1ec7c67212 Merge branch 'heads/main' into daniel/ms-teams-integration 2025-04-30 02:39:08 +04:00
Daniel Hougaard
ff0ff622a6 requested changes 2025-04-30 02:35:07 +04:00
carlosmonastyrski
511becabd8 Merge branch 'main' into feat/azureClientSecretsRotation 2025-04-29 19:26:14 -03:00
carlosmonastyrski
f0229c5ecf feat(user-auth): fix migration bug for e2e suite 2025-04-29 18:48:08 -03:00
carlosmonastyrski
8d711af23b feat(secrets-ui): change secret sync icon color 2025-04-29 18:39:41 -03:00
carlosmonastyrski
7bd61d88fc feat(user-auth): improve token refresh logic and default values 2025-04-29 18:28:18 -03:00
Tuan Dang
a9a16c9bd1 Begin work on ssh host groups 2025-04-29 13:39:24 -07:00
Daniel Hougaard
929434d17f docs: improved ms teams workflow integration self-hosting docs 2025-04-30 00:15:58 +04:00
Scott Wilson
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
Scott Wilson
b65f62fda8 fix: use hostname for blocking internal IPs 2025-04-29 12:26:29 -07:00
carlosmonastyrski
c47d76a6c7 feat(secrets-ui): improve warning message table 2025-04-29 14:19:52 -03:00
x032205
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
carlosmonastyrski
e959ed7fab feat(secrets-ui): improve warning message and logic for secret-sync on secret imports 2025-04-29 10:15:53 -03:00
carlosmonastyrski
4e4b1b689b Merge branch 'main' into feat/improveSecretReferenceWarning 2025-04-29 08:43:35 -03:00
Maidul Islam
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
Maidul Islam
023f5d1286 revise docs 2025-04-28 23:06:37 -04:00
Daniel Hougaard
72b03d4bdf Merge pull request #3506 from Infisical/daniel/build-strict-find-filter
feat: strict find filter
2025-04-29 05:41:39 +04:00
Daniel Hougaard
e870e35002 consolidated filtering functions into one 2025-04-29 04:27:10 +04:00
carlosmonastyrski
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
carlosmonastyrski
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
carlosmonastyrski
024ed0c0d8 feat(user-auth): add pr suggestions 2025-04-28 18:19:44 -03:00
carlosmonastyrski
e99e360339 feat(user-auth): make users auth token expiration customizable for orgs 2025-04-28 17:43:10 -03:00
Daniel Hougaard
85965184f8 Update secret-v2-bridge-dal.ts 2025-04-29 00:18:13 +04:00
Daniel Hougaard
a1bbd50c0b feat: build strict find filter 2025-04-29 00:09:30 +04:00
carlosmonastyrski
f9c936865a feat(secrets-ui): minor improvements from PR suggestions 2025-04-28 16:49:29 -03:00
=
6bca854475 doc: added doc for assume privilege feature 2025-04-29 00:12:37 +05:30
carlosmonastyrski
4fa7ba2ec7 Merge branch 'main' into fix/UISecretEditPermissionButNotReadValuePermission 2025-04-28 13:33:05 -03:00
Daniel Hougaard
f35cd2d6a6 Update project-service.ts 2025-04-28 05:20:56 +04:00
Daniel Hougaard
b259428075 fix: secret scanning & route mismatch 2025-04-28 05:16:33 +04:00
Daniel Hougaard
f54a10f626 Merge branch 'heads/main' into daniel/ms-teams-integration 2025-04-28 05:08:04 +04:00
Daniel Hougaard
63a3ce2dba feat(workflow-integrations): ms-teams audit logs and pagination support 2025-04-28 04:58:25 +04:00
Daniel Hougaard
9aabc3ced7 better error logs 2025-04-28 04:07:32 +04:00
Daniel Hougaard
fe9ec6b030 docs(workflow-integrations): microsoft teams 2025-04-28 04:07:01 +04:00
Daniel Hougaard
bef55043f7 Update OrgWorkflowIntegrationTab.tsx 2025-04-26 10:16:30 +04:00
Daniel Hougaard
0323d152da feat(microsoft-teams): better authentication flow and doc references 2025-04-26 09:46:23 +04:00
carlosmonastyrski
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
carlosmonastyrski
f345801bd6 feat(secrets-ui): improve types and code quality 2025-04-25 18:17:33 -03:00
carlosmonastyrski
f460acf9b4 fix(secrets-permissions): Fix case for rotated secrets 2025-04-25 17:56:56 -03:00
carlosmonastyrski
4160009913 feat(secrets-ui): add direct reference warning on secrets updates 2025-04-25 17:38:43 -03:00
carlosmonastyrski
d5065af7e9 feat(secrets-ui): add secret syncs to referenced secret warning 2025-04-25 15:26:34 -03:00
carlosmonastyrski
68e88ddef8 feat(azure-client-secrets-rotation): add show credentials modal 2025-04-25 13:16:13 -03:00
carlosmonastyrski
a2909b8030 Merge branch 'main' into feat/azureClientSecretsRotation 2025-04-25 12:42:48 -03:00
carlosmonastyrski
3de5fa066b fix(secrets-permissions): Fix setTimeout and eye icon size 2025-04-25 08:54:25 -03:00
Daniel Hougaard
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
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
Daniel Hougaard
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
Daniel Hougaard
a204629bef Merge branch 'heads/main' into daniel/ms-teams-integration 2025-04-25 05:22:35 +04:00
Daniel Hougaard
50679ba29d fix: requested changes 2025-04-25 05:22:17 +04:00
Daniel Hougaard
f5fa57d6c5 fix: further cleanup 2025-04-25 04:53:00 +04:00
Daniel Hougaard
6088ae09ab fix: cleanup 2025-04-25 04:40:46 +04:00
Daniel Hougaard
0de15bf70c fix: remove logs 2025-04-25 04:37:22 +04:00
Daniel Hougaard
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
x
418ac20f91 feat(app-connections): Hashicorp Vault App Connection 2025-04-24 15:41:21 -04:00
carlosmonastyrski
b377d2a6b1 fix(secrets-permissions): Fix setTimeout 2025-04-24 11:15:42 -03:00
carlosmonastyrski
350272aa57 fix(secrets-permissions): UI improvements 2025-04-24 08:10:10 -03:00
carlosmonastyrski
95489e1b0a fix(secrets-permissions): UI improvements 2025-04-23 22:24:41 -03:00
carlosmonastyrski
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
carlosmonastyrski
e30a05e3e8 Remove unnecessary password type 2025-04-22 15:49:05 -03:00
carlosmonastyrski
ce7798c48b Fix redirect url for azure secrets 2025-04-22 15:44:21 -03:00
carlosmonastyrski
6ce1c4e19e Merge branch 'main' into feat/azureClientSecretsRotation 2025-04-22 14:25:56 -03:00
carlosmonastyrski
f08de1599d PR fix suggestions 2025-04-22 14:25:52 -03:00
carlosmonastyrski
7d4f223174 lint fix 2025-04-21 10:36:27 -03:00
carlosmonastyrski
ef47d0056f Merge branch 'main' into feat/azureClientSecretsRotation 2025-04-21 10:27:56 -03:00
carlosmonastyrski
ccd7b0062e Fix MAX_GENERATED_CREDENTIALS_LENGTH for azure credentials 2025-04-21 10:14:55 -03:00
carlosmonastyrski
c403ffa9f6 Add Azure Client Secrets Rotation docs 2025-04-16 06:33:38 -03:00
carlosmonastyrski
1184ea1b11 Add Azure Client Secrets Rotation 2025-04-16 05:04:41 -03:00
carlosmonastyrski
7d97a76ecc Merge branch 'auth0-connection-and-secret-rotation' into feat/azureClientSecretsRotation 2025-04-15 23:58:27 -03:00
carlosmonastyrski
a889f92528 Add Azure Client Secrets App Connection 2025-04-15 23:39:06 -03:00
1396 changed files with 66508 additions and 16397 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();

7348
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": "",
@@ -96,6 +97,7 @@
"@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",
@@ -115,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",
@@ -128,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",
@@ -149,7 +153,8 @@
"@infisical/quic": "^1.0.8",
"@node-saml/passport-saml": "^5.0.1",
"@octokit/auth-app": "^7.1.1",
"@octokit/plugin-paginate-graphql": "^5.2.4",
"@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,6 +211,7 @@
"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",
@@ -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

@@ -41,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";
@@ -52,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";
@@ -65,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";
@@ -104,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?: {
@@ -144,6 +152,13 @@ declare module "fastify" {
providerAuthToken: string;
externalProviderAccessToken?: string;
};
passportMachineIdentity: {
identityId: string;
user: {
uid: string;
mail?: string;
};
};
kmipUser: {
projectId: string;
clientId: string;
@@ -151,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 {
@@ -195,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;
@@ -213,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;
@@ -246,8 +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,
@@ -119,6 +122,9 @@ import {
TIdentityMetadata,
TIdentityMetadataInsert,
TIdentityMetadataUpdate,
TIdentityOciAuths,
TIdentityOciAuthsInsert,
TIdentityOciAuthsUpdate,
TIdentityOidcAuths,
TIdentityOidcAuthsInsert,
TIdentityOidcAuthsUpdate,
@@ -152,6 +158,9 @@ import {
TIntegrations,
TIntegrationsInsert,
TIntegrationsUpdate,
TInternalCertificateAuthorities,
TInternalCertificateAuthoritiesInsert,
TInternalCertificateAuthoritiesUpdate,
TInternalKms,
TInternalKmsInsert,
TInternalKmsUpdate,
@@ -209,6 +218,9 @@ import {
TPkiCollections,
TPkiCollectionsInsert,
TPkiCollectionsUpdate,
TPkiSubscribers,
TPkiSubscribersInsert,
TPkiSubscribersUpdate,
TProjectBots,
TProjectBotsInsert,
TProjectBotsUpdate,
@@ -386,6 +398,12 @@ import {
TSshCertificateTemplates,
TSshCertificateTemplatesInsert,
TSshCertificateTemplatesUpdate,
TSshHostGroupMemberships,
TSshHostGroupMembershipsInsert,
TSshHostGroupMembershipsUpdate,
TSshHostGroups,
TSshHostGroupsInsert,
TSshHostGroupsUpdate,
TSshHostLoginUserMappings,
TSshHostLoginUserMappingsInsert,
TSshHostLoginUserMappingsUpdate,
@@ -426,6 +444,21 @@ 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,
@@ -445,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,
@@ -501,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,
@@ -533,6 +586,11 @@ declare module "knex/types/tables" {
TPkiCollectionItemsInsert,
TPkiCollectionItemsUpdate
>;
[TableName.PkiSubscriber]: KnexOriginal.CompositeTableType<
TPkiSubscribers,
TPkiSubscribersInsert,
TPkiSubscribersUpdate
>;
[TableName.UserGroupMembership]: KnexOriginal.CompositeTableType<
TUserGroupMembership,
TUserGroupMembershipInsert,
@@ -699,6 +757,11 @@ declare module "knex/types/tables" {
TIdentityAzureAuthsInsert,
TIdentityAzureAuthsUpdate
>;
[TableName.IdentityOciAuth]: KnexOriginal.CompositeTableType<
TIdentityOciAuths,
TIdentityOciAuthsInsert,
TIdentityOciAuthsUpdate
>;
[TableName.IdentityOidcAuth]: KnexOriginal.CompositeTableType<
TIdentityOidcAuths,
TIdentityOidcAuthsInsert,
@@ -709,6 +772,11 @@ declare module "knex/types/tables" {
TIdentityJwtAuthsInsert,
TIdentityJwtAuthsUpdate
>;
[TableName.IdentityLdapAuth]: KnexOriginal.CompositeTableType<
TIdentityLdapAuths,
TIdentityLdapAuthsInsert,
TIdentityLdapAuthsUpdate
>;
[TableName.IdentityUaClientSecret]: KnexOriginal.CompositeTableType<
TIdentityUaClientSecrets,
TIdentityUaClientSecretsInsert,
@@ -1002,6 +1070,16 @@ 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,

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,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(),
@@ -21,10 +21,12 @@ export const CertificatesSchema = z.object({
revokedAt: z.date().nullable().optional(),
revocationReason: z.number().nullable().optional(),
altNames: z.string().nullable().optional(),
caCertId: z.string().uuid(),
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

@@ -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,6 +20,7 @@ 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";
@@ -37,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";
@@ -48,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";
@@ -58,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";
@@ -68,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";
@@ -127,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

@@ -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",
@@ -147,6 +154,8 @@ export enum TableName {
KmipClientCertificates = "kmip_client_certificates",
SecretRotationV2 = "secret_rotations_v2",
SecretRotationV2SecretMapping = "secret_rotation_v2_secret_mappings",
MicrosoftTeamsIntegrations = "microsoft_teams_integrations",
ProjectMicrosoftTeamsConfigs = "project_microsoft_teams_configs",
SecretReminderRecipients = "secret_reminder_recipients",
GithubOrgSyncConfig = "github_org_sync_configs"
}
@@ -181,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 {
@@ -222,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

@@ -23,12 +23,20 @@ export const OrganizationsSchema = z.object({
defaultMembershipRole: z.string().default("member"),
enforceMfa: z.boolean().default(false),
selectedMfaMethod: z.string().nullable().optional(),
secretShareSendToAnyone: z.boolean().default(true).nullable().optional(),
allowSecretSharingOutsideOrganization: z.boolean().default(true).nullable().optional(),
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

@@ -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

@@ -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

@@ -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

@@ -34,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";
@@ -88,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,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,8 +3,9 @@ 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";
@@ -21,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()
})
)
}
@@ -49,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,
@@ -91,7 +104,9 @@ 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
@@ -119,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()
})
}
},
@@ -163,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)
@@ -192,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()
})
}
},
@@ -235,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()
})
}
},
@@ -278,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)
@@ -350,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)
@@ -414,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)
@@ -435,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,7 @@ 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";
@@ -15,6 +16,7 @@ export const SECRET_ROTATION_REGISTER_ROUTER_MAP: Record<
[SecretRotation.PostgresCredentials]: registerPostgresCredentialsRotationRouter,
[SecretRotation.MsSqlCredentials]: registerMsSqlCredentialsRotationRouter,
[SecretRotation.Auth0ClientSecret]: registerAuth0ClientSecretRotationRouter,
[SecretRotation.LdapPassword]: registerLdapPasswordRotationRouter,
[SecretRotation.AwsIamUserSecret]: registerAwsIamUserSecretRotationRouter
[SecretRotation.AzureClientSecret]: registerAzureClientSecretRotationRouter,
[SecretRotation.AwsIamUserSecret]: registerAwsIamUserSecretRotationRouter,
[SecretRotation.LdapPassword]: registerLdapPasswordRotationRouter
};

View File

@@ -3,6 +3,7 @@ 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";
@@ -16,8 +17,9 @@ const SecretRotationV2OptionsSchema = z.discriminatedUnion("type", [
PostgresCredentialsRotationListItemSchema,
MsSqlCredentialsRotationListItemSchema,
Auth0ClientSecretRotationListItemSchema,
LdapPasswordRotationListItemSchema,
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 = {

View File

@@ -0,0 +1,4 @@
export * from "./oci-connection-enums";
export * from "./oci-connection-fns";
export * from "./oci-connection-schemas";
export * from "./oci-connection-types";

View File

@@ -0,0 +1,3 @@
export enum OCIConnectionMethod {
AccessKey = "access-key"
}

View File

@@ -0,0 +1,139 @@
import { common, identity, keymanagement } from "oci-sdk";
import { BadRequestError } from "@app/lib/errors";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { OCIConnectionMethod } from "./oci-connection-enums";
import { TOCIConnection, TOCIConnectionConfig } from "./oci-connection-types";
export const getOCIProvider = async (config: TOCIConnectionConfig) => {
const {
credentials: { fingerprint, privateKey, region, tenancyOcid, userOcid }
} = config;
const provider = new common.SimpleAuthenticationDetailsProvider(
tenancyOcid,
userOcid,
fingerprint,
privateKey,
null,
common.Region.fromRegionId(region)
);
return provider;
};
export const getOCIConnectionListItem = () => {
return {
name: "OCI" as const,
app: AppConnection.OCI as const,
methods: Object.values(OCIConnectionMethod) as [OCIConnectionMethod.AccessKey]
};
};
export const validateOCIConnectionCredentials = async (config: TOCIConnectionConfig) => {
const provider = await getOCIProvider(config);
try {
const identityClient = new identity.IdentityClient({
authenticationDetailsProvider: provider
});
// Get user details - a lightweight call that validates all credentials
await identityClient.getUser({ userId: config.credentials.userOcid });
} catch (error: unknown) {
if (error instanceof Error) {
throw new BadRequestError({
message: `Failed to validate credentials: ${error.message || "Unknown error"}`
});
}
throw new BadRequestError({
message: "Unable to validate connection: verify credentials"
});
}
return config.credentials;
};
export const listOCICompartments = async (appConnection: TOCIConnection) => {
const provider = await getOCIProvider(appConnection);
const identityClient = new identity.IdentityClient({ authenticationDetailsProvider: provider });
const keyManagementClient = new keymanagement.KmsVaultClient({
authenticationDetailsProvider: provider
});
const rootCompartment = await identityClient
.getTenancy({
tenancyId: appConnection.credentials.tenancyOcid
})
.then((response) => ({
...response.tenancy,
id: appConnection.credentials.tenancyOcid,
name: response.tenancy.name ? `${response.tenancy.name} (root)` : "root"
}));
const compartments = await identityClient.listCompartments({
compartmentId: appConnection.credentials.tenancyOcid,
compartmentIdInSubtree: true,
accessLevel: identity.requests.ListCompartmentsRequest.AccessLevel.Any,
lifecycleState: identity.models.Compartment.LifecycleState.Active
});
const allCompartments = [rootCompartment, ...compartments.items];
const filteredCompartments = [];
for await (const compartment of allCompartments) {
try {
// Check if user can list vaults in this compartment
await keyManagementClient.listVaults({
compartmentId: compartment.id,
limit: 1
});
filteredCompartments.push(compartment);
} catch (error) {
// Do nothing
}
}
return filteredCompartments;
};
export const listOCIVaults = async (appConnection: TOCIConnection, compartmentOcid: string) => {
const provider = await getOCIProvider(appConnection);
const keyManagementClient = new keymanagement.KmsVaultClient({
authenticationDetailsProvider: provider
});
const vaults = await keyManagementClient.listVaults({
compartmentId: compartmentOcid
});
return vaults.items.filter((v) => v.lifecycleState === keymanagement.models.Vault.LifecycleState.Active);
};
export const listOCIVaultKeys = async (appConnection: TOCIConnection, compartmentOcid: string, vaultOcid: string) => {
const provider = await getOCIProvider(appConnection);
const kmsVaultClient = new keymanagement.KmsVaultClient({
authenticationDetailsProvider: provider
});
const vault = await kmsVaultClient.getVault({
vaultId: vaultOcid
});
const keyManagementClient = new keymanagement.KmsManagementClient({
authenticationDetailsProvider: provider
});
keyManagementClient.endpoint = vault.vault.managementEndpoint;
const keys = await keyManagementClient.listKeys({
compartmentId: compartmentOcid
});
return keys.items.filter((v) => v.lifecycleState === keymanagement.models.KeySummary.LifecycleState.Enabled);
};

View File

@@ -0,0 +1,65 @@
import z from "zod";
import { AppConnections } from "@app/lib/api-docs";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import {
BaseAppConnectionSchema,
GenericCreateAppConnectionFieldsSchema,
GenericUpdateAppConnectionFieldsSchema
} from "@app/services/app-connection/app-connection-schemas";
import { OCIConnectionMethod } from "./oci-connection-enums";
export const OCIConnectionAccessTokenCredentialsSchema = z.object({
userOcid: z.string().trim().min(1, "User OCID required").describe(AppConnections.CREDENTIALS.OCI.userOcid),
tenancyOcid: z.string().trim().min(1, "Tenancy OCID required").describe(AppConnections.CREDENTIALS.OCI.tenancyOcid),
region: z.string().trim().min(1, "Region required").describe(AppConnections.CREDENTIALS.OCI.region),
fingerprint: z.string().trim().min(1, "Fingerprint required").describe(AppConnections.CREDENTIALS.OCI.fingerprint),
privateKey: z.string().trim().min(1, "Private Key required").describe(AppConnections.CREDENTIALS.OCI.privateKey)
});
const BaseOCIConnectionSchema = BaseAppConnectionSchema.extend({ app: z.literal(AppConnection.OCI) });
export const OCIConnectionSchema = BaseOCIConnectionSchema.extend({
method: z.literal(OCIConnectionMethod.AccessKey),
credentials: OCIConnectionAccessTokenCredentialsSchema
});
export const SanitizedOCIConnectionSchema = z.discriminatedUnion("method", [
BaseOCIConnectionSchema.extend({
method: z.literal(OCIConnectionMethod.AccessKey),
credentials: OCIConnectionAccessTokenCredentialsSchema.pick({
userOcid: true,
tenancyOcid: true,
region: true,
fingerprint: true
})
})
]);
export const ValidateOCIConnectionCredentialsSchema = z.discriminatedUnion("method", [
z.object({
method: z.literal(OCIConnectionMethod.AccessKey).describe(AppConnections.CREATE(AppConnection.OCI).method),
credentials: OCIConnectionAccessTokenCredentialsSchema.describe(
AppConnections.CREATE(AppConnection.OCI).credentials
)
})
]);
export const CreateOCIConnectionSchema = ValidateOCIConnectionCredentialsSchema.and(
GenericCreateAppConnectionFieldsSchema(AppConnection.OCI)
);
export const UpdateOCIConnectionSchema = z
.object({
credentials: OCIConnectionAccessTokenCredentialsSchema.optional().describe(
AppConnections.UPDATE(AppConnection.OCI).credentials
)
})
.and(GenericUpdateAppConnectionFieldsSchema(AppConnection.OCI));
export const OCIConnectionListItemSchema = z.object({
name: z.literal("OCI"),
app: z.literal(AppConnection.OCI),
methods: z.nativeEnum(OCIConnectionMethod).array()
});

View File

@@ -0,0 +1,91 @@
import { BadRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
import { OrgServiceActor } from "@app/lib/types";
import { AppConnection } from "../../../../services/app-connection/app-connection-enums";
import { TLicenseServiceFactory } from "../../license/license-service";
import { listOCICompartments, listOCIVaultKeys, listOCIVaults } from "./oci-connection-fns";
import { TOCIConnection } from "./oci-connection-types";
type TGetAppConnectionFunc = (
app: AppConnection,
connectionId: string,
actor: OrgServiceActor
) => Promise<TOCIConnection>;
type TListOCIVaultsDTO = {
connectionId: string;
compartmentOcid: string;
};
type TListOCIVaultKeysDTO = {
connectionId: string;
compartmentOcid: string;
vaultOcid: string;
};
// Enterprise check
export const checkPlan = async (licenseService: Pick<TLicenseServiceFactory, "getPlan">, orgId: string) => {
const plan = await licenseService.getPlan(orgId);
if (!plan.enterpriseAppConnections)
throw new BadRequestError({
message:
"Failed to use app connection due to plan restriction. Upgrade plan to access enterprise app connections."
});
};
export const ociConnectionService = (
getAppConnection: TGetAppConnectionFunc,
licenseService: Pick<TLicenseServiceFactory, "getPlan">
) => {
const listCompartments = async (connectionId: string, actor: OrgServiceActor) => {
await checkPlan(licenseService, actor.orgId);
const appConnection = await getAppConnection(AppConnection.OCI, connectionId, actor);
try {
const compartments = await listOCICompartments(appConnection);
return compartments;
} catch (error) {
logger.error(error, "Failed to establish connection with OCI");
return [];
}
};
const listVaults = async ({ connectionId, compartmentOcid }: TListOCIVaultsDTO, actor: OrgServiceActor) => {
await checkPlan(licenseService, actor.orgId);
const appConnection = await getAppConnection(AppConnection.OCI, connectionId, actor);
try {
const vaults = await listOCIVaults(appConnection, compartmentOcid);
return vaults;
} catch (error) {
logger.error(error, "Failed to establish connection with OCI");
return [];
}
};
const listVaultKeys = async (
{ connectionId, compartmentOcid, vaultOcid }: TListOCIVaultKeysDTO,
actor: OrgServiceActor
) => {
await checkPlan(licenseService, actor.orgId);
const appConnection = await getAppConnection(AppConnection.OCI, connectionId, actor);
try {
const keys = await listOCIVaultKeys(appConnection, compartmentOcid, vaultOcid);
return keys;
} catch (error) {
logger.error(error, "Failed to establish connection with OCI");
return [];
}
};
return {
listCompartments,
listVaults,
listVaultKeys
};
};

View File

@@ -0,0 +1,22 @@
import z from "zod";
import { DiscriminativePick } from "@app/lib/types";
import { AppConnection } from "../../../../services/app-connection/app-connection-enums";
import {
CreateOCIConnectionSchema,
OCIConnectionSchema,
ValidateOCIConnectionCredentialsSchema
} from "./oci-connection-schemas";
export type TOCIConnection = z.infer<typeof OCIConnectionSchema>;
export type TOCIConnectionInput = z.infer<typeof CreateOCIConnectionSchema> & {
app: AppConnection.OCI;
};
export type TValidateOCIConnectionCredentialsSchema = typeof ValidateOCIConnectionCredentialsSchema;
export type TOCIConnectionConfig = DiscriminativePick<TOCIConnectionInput, "method" | "app" | "credentials"> & {
orgId: string;
};

View File

@@ -1,3 +1,4 @@
import { ProjectType } from "@app/db/schemas";
import {
TCreateProjectTemplateDTO,
TUpdateProjectTemplateDTO
@@ -12,15 +13,17 @@ import {
import { SshCaStatus, SshCertType } from "@app/ee/services/ssh/ssh-certificate-authority-types";
import { SshCertKeyAlgorithm } from "@app/ee/services/ssh-certificate/ssh-certificate-types";
import { SshCertTemplateStatus } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-types";
import { TLoginMapping } from "@app/ee/services/ssh-host/ssh-host-types";
import { SymmetricKeyAlgorithm } from "@app/lib/crypto/cipher";
import { AsymmetricKeyAlgorithm, SigningAlgorithm } from "@app/lib/crypto/sign/types";
import { TProjectPermission } from "@app/lib/types";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { TCreateAppConnectionDTO, TUpdateAppConnectionDTO } from "@app/services/app-connection/app-connection-types";
import { ActorType } from "@app/services/auth/auth-type";
import { CertKeyAlgorithm } from "@app/services/certificate/certificate-types";
import { CaStatus } from "@app/services/certificate-authority/certificate-authority-types";
import { CertExtendedKeyUsage, CertKeyAlgorithm, CertKeyUsage } from "@app/services/certificate/certificate-types";
import { CaStatus } from "@app/services/certificate-authority/certificate-authority-enums";
import { TIdentityTrustedIp } from "@app/services/identity/identity-types";
import { TAllowedFields } from "@app/services/identity-ldap-auth/identity-ldap-auth-types";
import { PkiItemType } from "@app/services/pki-collection/pki-collection-types";
import { SecretSync, SecretSyncImportBehavior } from "@app/services/secret-sync/secret-sync-enums";
import {
@@ -29,6 +32,7 @@ import {
TSecretSyncRaw,
TUpdateSecretSyncDTO
} from "@app/services/secret-sync/secret-sync-types";
import { WorkflowIntegration } from "@app/services/workflow-integration/workflow-integration-types";
import { KmipPermission } from "../kmip/kmip-enum";
import { ApprovalStatus } from "../secret-approval-request/secret-approval-request-types";
@@ -117,44 +121,66 @@ export enum EventType {
CREATE_TOKEN_IDENTITY_TOKEN_AUTH = "create-token-identity-token-auth",
UPDATE_TOKEN_IDENTITY_TOKEN_AUTH = "update-token-identity-token-auth",
GET_TOKENS_IDENTITY_TOKEN_AUTH = "get-tokens-identity-token-auth",
ADD_IDENTITY_TOKEN_AUTH = "add-identity-token-auth",
UPDATE_IDENTITY_TOKEN_AUTH = "update-identity-token-auth",
GET_IDENTITY_TOKEN_AUTH = "get-identity-token-auth",
REVOKE_IDENTITY_TOKEN_AUTH = "revoke-identity-token-auth",
LOGIN_IDENTITY_KUBERNETES_AUTH = "login-identity-kubernetes-auth",
ADD_IDENTITY_KUBERNETES_AUTH = "add-identity-kubernetes-auth",
UPDATE_IDENTITY_KUBENETES_AUTH = "update-identity-kubernetes-auth",
GET_IDENTITY_KUBERNETES_AUTH = "get-identity-kubernetes-auth",
REVOKE_IDENTITY_KUBERNETES_AUTH = "revoke-identity-kubernetes-auth",
LOGIN_IDENTITY_OIDC_AUTH = "login-identity-oidc-auth",
ADD_IDENTITY_OIDC_AUTH = "add-identity-oidc-auth",
UPDATE_IDENTITY_OIDC_AUTH = "update-identity-oidc-auth",
GET_IDENTITY_OIDC_AUTH = "get-identity-oidc-auth",
REVOKE_IDENTITY_OIDC_AUTH = "revoke-identity-oidc-auth",
LOGIN_IDENTITY_JWT_AUTH = "login-identity-jwt-auth",
ADD_IDENTITY_JWT_AUTH = "add-identity-jwt-auth",
UPDATE_IDENTITY_JWT_AUTH = "update-identity-jwt-auth",
GET_IDENTITY_JWT_AUTH = "get-identity-jwt-auth",
REVOKE_IDENTITY_JWT_AUTH = "revoke-identity-jwt-auth",
CREATE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "create-identity-universal-auth-client-secret",
REVOKE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "revoke-identity-universal-auth-client-secret",
GET_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRETS = "get-identity-universal-auth-client-secret",
GET_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET_BY_ID = "get-identity-universal-auth-client-secret-by-id",
LOGIN_IDENTITY_GCP_AUTH = "login-identity-gcp-auth",
ADD_IDENTITY_GCP_AUTH = "add-identity-gcp-auth",
UPDATE_IDENTITY_GCP_AUTH = "update-identity-gcp-auth",
REVOKE_IDENTITY_GCP_AUTH = "revoke-identity-gcp-auth",
GET_IDENTITY_GCP_AUTH = "get-identity-gcp-auth",
LOGIN_IDENTITY_AWS_AUTH = "login-identity-aws-auth",
ADD_IDENTITY_AWS_AUTH = "add-identity-aws-auth",
UPDATE_IDENTITY_AWS_AUTH = "update-identity-aws-auth",
REVOKE_IDENTITY_AWS_AUTH = "revoke-identity-aws-auth",
GET_IDENTITY_AWS_AUTH = "get-identity-aws-auth",
LOGIN_IDENTITY_OCI_AUTH = "login-identity-oci-auth",
ADD_IDENTITY_OCI_AUTH = "add-identity-oci-auth",
UPDATE_IDENTITY_OCI_AUTH = "update-identity-oci-auth",
REVOKE_IDENTITY_OCI_AUTH = "revoke-identity-oci-auth",
GET_IDENTITY_OCI_AUTH = "get-identity-oci-auth",
LOGIN_IDENTITY_AZURE_AUTH = "login-identity-azure-auth",
ADD_IDENTITY_AZURE_AUTH = "add-identity-azure-auth",
UPDATE_IDENTITY_AZURE_AUTH = "update-identity-azure-auth",
GET_IDENTITY_AZURE_AUTH = "get-identity-azure-auth",
REVOKE_IDENTITY_AZURE_AUTH = "revoke-identity-azure-auth",
LOGIN_IDENTITY_LDAP_AUTH = "login-identity-ldap-auth",
ADD_IDENTITY_LDAP_AUTH = "add-identity-ldap-auth",
UPDATE_IDENTITY_LDAP_AUTH = "update-identity-ldap-auth",
GET_IDENTITY_LDAP_AUTH = "get-identity-ldap-auth",
REVOKE_IDENTITY_LDAP_AUTH = "revoke-identity-ldap-auth",
CREATE_ENVIRONMENT = "create-environment",
UPDATE_ENVIRONMENT = "update-environment",
DELETE_ENVIRONMENT = "delete-environment",
@@ -191,14 +217,22 @@ export enum EventType {
UPDATE_SSH_CERTIFICATE_TEMPLATE = "update-ssh-certificate-template",
DELETE_SSH_CERTIFICATE_TEMPLATE = "delete-ssh-certificate-template",
GET_SSH_CERTIFICATE_TEMPLATE = "get-ssh-certificate-template",
GET_SSH_HOST = "get-ssh-host",
CREATE_SSH_HOST = "create-ssh-host",
UPDATE_SSH_HOST = "update-ssh-host",
DELETE_SSH_HOST = "delete-ssh-host",
GET_SSH_HOST = "get-ssh-host",
ISSUE_SSH_HOST_USER_CERT = "issue-ssh-host-user-cert",
ISSUE_SSH_HOST_HOST_CERT = "issue-ssh-host-host-cert",
GET_SSH_HOST_GROUP = "get-ssh-host-group",
CREATE_SSH_HOST_GROUP = "create-ssh-host-group",
UPDATE_SSH_HOST_GROUP = "update-ssh-host-group",
DELETE_SSH_HOST_GROUP = "delete-ssh-host-group",
GET_SSH_HOST_GROUP_HOSTS = "get-ssh-host-group-hosts",
ADD_HOST_TO_SSH_HOST_GROUP = "add-host-to-ssh-host-group",
REMOVE_HOST_FROM_SSH_HOST_GROUP = "remove-host-from-ssh-host-group",
CREATE_CA = "create-certificate-authority",
GET_CA = "get-certificate-authority",
GET_CAS = "get-certificate-authorities",
UPDATE_CA = "update-certificate-authority",
DELETE_CA = "delete-certificate-authority",
RENEW_CA = "renew-certificate-authority",
@@ -209,12 +243,15 @@ export enum EventType {
IMPORT_CA_CERT = "import-certificate-authority-cert",
GET_CA_CRLS = "get-certificate-authority-crls",
ISSUE_CERT = "issue-cert",
IMPORT_CERT = "import-cert",
SIGN_CERT = "sign-cert",
GET_CA_CERTIFICATE_TEMPLATES = "get-ca-certificate-templates",
GET_CERT = "get-cert",
DELETE_CERT = "delete-cert",
REVOKE_CERT = "revoke-cert",
GET_CERT_BODY = "get-cert-body",
GET_CERT_PRIVATE_KEY = "get-cert-private-key",
GET_CERT_BUNDLE = "get-cert-bundle",
CREATE_PKI_ALERT = "create-pki-alert",
GET_PKI_ALERT = "get-pki-alert",
UPDATE_PKI_ALERT = "update-pki-alert",
@@ -226,6 +263,15 @@ export enum EventType {
GET_PKI_COLLECTION_ITEMS = "get-pki-collection-items",
ADD_PKI_COLLECTION_ITEM = "add-pki-collection-item",
DELETE_PKI_COLLECTION_ITEM = "delete-pki-collection-item",
CREATE_PKI_SUBSCRIBER = "create-pki-subscriber",
UPDATE_PKI_SUBSCRIBER = "update-pki-subscriber",
DELETE_PKI_SUBSCRIBER = "delete-pki-subscriber",
GET_PKI_SUBSCRIBER = "get-pki-subscriber",
ISSUE_PKI_SUBSCRIBER_CERT = "issue-pki-subscriber-cert",
SIGN_PKI_SUBSCRIBER_CERT = "sign-pki-subscriber-cert",
AUTOMATED_RENEW_SUBSCRIBER_CERT = "automated-renew-subscriber-cert",
LIST_PKI_SUBSCRIBER_CERTS = "list-pki-subscriber-certs",
GET_SUBSCRIBER_ACTIVE_CERT_BUNDLE = "get-subscriber-active-cert-bundle",
CREATE_KMS = "create-kms",
UPDATE_KMS = "update-kms",
DELETE_KMS = "delete-kms",
@@ -244,11 +290,14 @@ export enum EventType {
GET_CERTIFICATE_TEMPLATE_EST_CONFIG = "get-certificate-template-est-config",
ATTEMPT_CREATE_SLACK_INTEGRATION = "attempt-create-slack-integration",
ATTEMPT_REINSTALL_SLACK_INTEGRATION = "attempt-reinstall-slack-integration",
GET_PROJECT_SLACK_CONFIG = "get-project-slack-config",
UPDATE_PROJECT_SLACK_CONFIG = "update-project-slack-config",
GET_SLACK_INTEGRATION = "get-slack-integration",
UPDATE_SLACK_INTEGRATION = "update-slack-integration",
DELETE_SLACK_INTEGRATION = "delete-slack-integration",
GET_PROJECT_SLACK_CONFIG = "get-project-slack-config",
UPDATE_PROJECT_SLACK_CONFIG = "update-project-slack-config",
GET_PROJECT_WORKFLOW_INTEGRATION_CONFIG = "get-project-workflow-integration-config",
UPDATE_PROJECT_WORKFLOW_INTEGRATION_CONFIG = "update-project-workflow-integration-config",
GET_PROJECT_SSH_CONFIG = "get-project-ssh-config",
UPDATE_PROJECT_SSH_CONFIG = "update-project-ssh-config",
INTEGRATION_SYNCED = "integration-synced",
@@ -271,7 +320,6 @@ export enum EventType {
CREATE_PROJECT_TEMPLATE = "create-project-template",
UPDATE_PROJECT_TEMPLATE = "update-project-template",
DELETE_PROJECT_TEMPLATE = "delete-project-template",
APPLY_PROJECT_TEMPLATE = "apply-project-template",
GET_APP_CONNECTIONS = "get-app-connections",
GET_AVAILABLE_APP_CONNECTIONS_DETAILS = "get-available-app-connections-details",
GET_APP_CONNECTION = "get-app-connection",
@@ -321,8 +369,23 @@ export enum EventType {
SECRET_ROTATION_ROTATE_SECRETS = "secret-rotation-rotate-secrets",
PROJECT_ACCESS_REQUEST = "project-access-request",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_CREATE = "microsoft-teams-workflow-integration-create",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_DELETE = "microsoft-teams-workflow-integration-delete",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_UPDATE = "microsoft-teams-workflow-integration-update",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_CHECK_INSTALLATION_STATUS = "microsoft-teams-workflow-integration-check-installation-status",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_GET_TEAMS = "microsoft-teams-workflow-integration-get-teams",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_GET = "microsoft-teams-workflow-integration-get",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_LIST = "microsoft-teams-workflow-integration-list",
PROJECT_ASSUME_PRIVILEGE_SESSION_START = "project-assume-privileges-session-start",
PROJECT_ASSUME_PRIVILEGE_SESSION_END = "project-assume-privileges-session-end"
PROJECT_ASSUME_PRIVILEGE_SESSION_END = "project-assume-privileges-session-end",
UPDATE_ORG = "update-org",
CREATE_PROJECT = "create-project",
UPDATE_PROJECT = "update-project",
DELETE_PROJECT = "delete-project"
}
export const filterableSecretEvents: EventType[] = [
@@ -962,6 +1025,55 @@ interface GetIdentityAwsAuthEvent {
};
}
interface LoginIdentityOciAuthEvent {
type: EventType.LOGIN_IDENTITY_OCI_AUTH;
metadata: {
identityId: string;
identityOciAuthId: string;
identityAccessTokenId: string;
};
}
interface AddIdentityOciAuthEvent {
type: EventType.ADD_IDENTITY_OCI_AUTH;
metadata: {
identityId: string;
tenancyOcid: string;
allowedUsernames: string | null;
accessTokenTTL: number;
accessTokenMaxTTL: number;
accessTokenNumUsesLimit: number;
accessTokenTrustedIps: Array<TIdentityTrustedIp>;
};
}
interface DeleteIdentityOciAuthEvent {
type: EventType.REVOKE_IDENTITY_OCI_AUTH;
metadata: {
identityId: string;
};
}
interface UpdateIdentityOciAuthEvent {
type: EventType.UPDATE_IDENTITY_OCI_AUTH;
metadata: {
identityId: string;
tenancyOcid?: string;
allowedUsernames: string | null;
accessTokenTTL?: number;
accessTokenMaxTTL?: number;
accessTokenNumUsesLimit?: number;
accessTokenTrustedIps?: Array<TIdentityTrustedIp>;
};
}
interface GetIdentityOciAuthEvent {
type: EventType.GET_IDENTITY_OCI_AUTH;
metadata: {
identityId: string;
};
}
interface LoginIdentityAzureAuthEvent {
type: EventType.LOGIN_IDENTITY_AZURE_AUTH;
metadata: {
@@ -1011,6 +1123,55 @@ interface GetIdentityAzureAuthEvent {
};
}
interface LoginIdentityLdapAuthEvent {
type: EventType.LOGIN_IDENTITY_LDAP_AUTH;
metadata: {
identityId: string;
ldapUsername: string;
ldapEmail?: string;
};
}
interface AddIdentityLdapAuthEvent {
type: EventType.ADD_IDENTITY_LDAP_AUTH;
metadata: {
identityId: string;
accessTokenTTL?: number;
accessTokenMaxTTL?: number;
accessTokenNumUsesLimit?: number;
accessTokenTrustedIps?: Array<TIdentityTrustedIp>;
allowedFields?: TAllowedFields[];
url: string;
};
}
interface UpdateIdentityLdapAuthEvent {
type: EventType.UPDATE_IDENTITY_LDAP_AUTH;
metadata: {
identityId: string;
accessTokenTTL?: number;
accessTokenMaxTTL?: number;
accessTokenNumUsesLimit?: number;
accessTokenTrustedIps?: Array<TIdentityTrustedIp>;
allowedFields?: TAllowedFields[];
url?: string;
};
}
interface GetIdentityLdapAuthEvent {
type: EventType.GET_IDENTITY_LDAP_AUTH;
metadata: {
identityId: string;
};
}
interface RevokeIdentityLdapAuthEvent {
type: EventType.REVOKE_IDENTITY_LDAP_AUTH;
metadata: {
identityId: string;
};
}
interface LoginIdentityOidcAuthEvent {
type: EventType.LOGIN_IDENTITY_OIDC_AUTH;
metadata: {
@@ -1499,12 +1660,7 @@ interface CreateSshHost {
alias: string | null;
userCertTtl: string;
hostCertTtl: string;
loginMappings: {
loginUser: string;
allowedPrincipals: {
usernames: string[];
};
}[];
loginMappings: TLoginMapping[];
userSshCaId: string;
hostSshCaId: string;
};
@@ -1518,12 +1674,7 @@ interface UpdateSshHost {
alias?: string | null;
userCertTtl?: string;
hostCertTtl?: string;
loginMappings?: {
loginUser: string;
allowedPrincipals: {
usernames: string[];
};
}[];
loginMappings?: TLoginMapping[];
userSshCaId?: string;
hostSshCaId?: string;
};
@@ -1567,11 +1718,72 @@ interface IssueSshHostHostCert {
};
}
interface GetSshHostGroupEvent {
type: EventType.GET_SSH_HOST_GROUP;
metadata: {
sshHostGroupId: string;
name: string;
};
}
interface CreateSshHostGroupEvent {
type: EventType.CREATE_SSH_HOST_GROUP;
metadata: {
sshHostGroupId: string;
name: string;
loginMappings: TLoginMapping[];
};
}
interface UpdateSshHostGroupEvent {
type: EventType.UPDATE_SSH_HOST_GROUP;
metadata: {
sshHostGroupId: string;
name?: string;
loginMappings?: TLoginMapping[];
};
}
interface DeleteSshHostGroupEvent {
type: EventType.DELETE_SSH_HOST_GROUP;
metadata: {
sshHostGroupId: string;
name: string;
};
}
interface GetSshHostGroupHostsEvent {
type: EventType.GET_SSH_HOST_GROUP_HOSTS;
metadata: {
sshHostGroupId: string;
name: string;
};
}
interface AddHostToSshHostGroupEvent {
type: EventType.ADD_HOST_TO_SSH_HOST_GROUP;
metadata: {
sshHostGroupId: string;
sshHostId: string;
hostname: string;
};
}
interface RemoveHostFromSshHostGroupEvent {
type: EventType.REMOVE_HOST_FROM_SSH_HOST_GROUP;
metadata: {
sshHostGroupId: string;
sshHostId: string;
hostname: string;
};
}
interface CreateCa {
type: EventType.CREATE_CA;
metadata: {
caId: string;
dn: string;
name: string;
dn?: string;
};
}
@@ -1579,7 +1791,15 @@ interface GetCa {
type: EventType.GET_CA;
metadata: {
caId: string;
dn: string;
name: string;
dn?: string;
};
}
interface GetCAs {
type: EventType.GET_CAS;
metadata: {
caIds: string[];
};
}
@@ -1587,7 +1807,8 @@ interface UpdateCa {
type: EventType.UPDATE_CA;
metadata: {
caId: string;
dn: string;
name: string;
dn?: string;
status: CaStatus;
};
}
@@ -1596,7 +1817,8 @@ interface DeleteCa {
type: EventType.DELETE_CA;
metadata: {
caId: string;
dn: string;
name: string;
dn?: string;
};
}
@@ -1666,6 +1888,15 @@ interface IssueCert {
};
}
interface ImportCert {
type: EventType.IMPORT_CERT;
metadata: {
certId: string;
cn: string;
serialNumber: string;
};
}
interface SignCert {
type: EventType.SIGN_CERT;
metadata: {
@@ -1719,6 +1950,24 @@ interface GetCertBody {
};
}
interface GetCertPrivateKey {
type: EventType.GET_CERT_PRIVATE_KEY;
metadata: {
certId: string;
cn: string;
serialNumber: string;
};
}
interface GetCertBundle {
type: EventType.GET_CERT_BUNDLE;
metadata: {
certId: string;
cn: string;
serialNumber: string;
};
}
interface CreatePkiAlert {
type: EventType.CREATE_PKI_ALERT;
metadata: {
@@ -1808,6 +2057,95 @@ interface DeletePkiCollectionItem {
};
}
interface CreatePkiSubscriber {
type: EventType.CREATE_PKI_SUBSCRIBER;
metadata: {
pkiSubscriberId: string;
caId?: string;
name: string;
commonName: string;
ttl?: string;
subjectAlternativeNames: string[];
keyUsages: CertKeyUsage[];
extendedKeyUsages: CertExtendedKeyUsage[];
};
}
interface UpdatePkiSubscriber {
type: EventType.UPDATE_PKI_SUBSCRIBER;
metadata: {
pkiSubscriberId: string;
caId?: string;
name?: string;
commonName?: string;
ttl?: string;
subjectAlternativeNames?: string[];
keyUsages?: CertKeyUsage[];
extendedKeyUsages?: CertExtendedKeyUsage[];
};
}
interface DeletePkiSubscriber {
type: EventType.DELETE_PKI_SUBSCRIBER;
metadata: {
pkiSubscriberId: string;
name: string;
};
}
interface GetPkiSubscriber {
type: EventType.GET_PKI_SUBSCRIBER;
metadata: {
pkiSubscriberId: string;
name: string;
};
}
interface IssuePkiSubscriberCert {
type: EventType.ISSUE_PKI_SUBSCRIBER_CERT;
metadata: {
subscriberId: string;
name: string;
serialNumber?: string;
};
}
interface AutomatedRenewPkiSubscriberCert {
type: EventType.AUTOMATED_RENEW_SUBSCRIBER_CERT;
metadata: {
subscriberId: string;
name: string;
};
}
interface SignPkiSubscriberCert {
type: EventType.SIGN_PKI_SUBSCRIBER_CERT;
metadata: {
subscriberId: string;
name: string;
serialNumber: string;
};
}
interface ListPkiSubscriberCerts {
type: EventType.LIST_PKI_SUBSCRIBER_CERTS;
metadata: {
subscriberId: string;
name: string;
projectId: string;
};
}
interface GetSubscriberActiveCertBundle {
type: EventType.GET_SUBSCRIBER_ACTIVE_CERT_BUNDLE;
metadata: {
subscriberId: string;
name: string;
certId: string;
serialNumber: string;
};
}
interface CreateKmsEvent {
type: EventType.CREATE_KMS;
metadata: {
@@ -1980,22 +2318,24 @@ interface GetSlackIntegration {
};
}
interface UpdateProjectSlackConfig {
type: EventType.UPDATE_PROJECT_SLACK_CONFIG;
interface UpdateProjectWorkflowIntegrationConfig {
type: EventType.UPDATE_PROJECT_WORKFLOW_INTEGRATION_CONFIG;
metadata: {
id: string;
slackIntegrationId: string;
integrationId: string;
integration: WorkflowIntegration;
isAccessRequestNotificationEnabled: boolean;
accessRequestChannels: string;
accessRequestChannels?: string | { teamId: string; channelIds: string[] };
isSecretRequestNotificationEnabled: boolean;
secretRequestChannels: string;
secretRequestChannels?: string | { teamId: string; channelIds: string[] };
};
}
interface GetProjectSlackConfig {
type: EventType.GET_PROJECT_SLACK_CONFIG;
interface GetProjectWorkflowIntegrationConfig {
type: EventType.GET_PROJECT_WORKFLOW_INTEGRATION_CONFIG;
metadata: {
id: string;
integration: WorkflowIntegration;
};
}
@@ -2159,14 +2499,6 @@ interface DeleteProjectTemplateEvent {
};
}
interface ApplyProjectTemplateEvent {
type: EventType.APPLY_PROJECT_TEMPLATE;
metadata: {
template: string;
projectId: string;
};
}
interface GetAppConnectionsEvent {
type: EventType.GET_APP_CONNECTIONS;
metadata: {
@@ -2561,6 +2893,119 @@ interface RotateSecretRotationEvent {
};
}
interface MicrosoftTeamsWorkflowIntegrationCreateEvent {
type: EventType.MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_CREATE;
metadata: {
tenantId: string;
slug: string;
description?: string;
};
}
interface MicrosoftTeamsWorkflowIntegrationDeleteEvent {
type: EventType.MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_DELETE;
metadata: {
tenantId: string;
id: string;
slug: string;
};
}
interface MicrosoftTeamsWorkflowIntegrationCheckInstallationStatusEvent {
type: EventType.MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_CHECK_INSTALLATION_STATUS;
metadata: {
tenantId: string;
slug: string;
};
}
interface MicrosoftTeamsWorkflowIntegrationGetTeamsEvent {
type: EventType.MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_GET_TEAMS;
metadata: {
tenantId: string;
slug: string;
id: string;
};
}
interface MicrosoftTeamsWorkflowIntegrationGetEvent {
type: EventType.MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_GET;
metadata: {
tenantId: string;
slug: string;
id: string;
};
}
interface MicrosoftTeamsWorkflowIntegrationListEvent {
type: EventType.MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_LIST;
metadata: Record<string, string>;
}
interface MicrosoftTeamsWorkflowIntegrationUpdateEvent {
type: EventType.MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_UPDATE;
metadata: {
tenantId: string;
slug: string;
id: string;
newSlug?: string;
newDescription?: string;
};
}
interface OrgUpdateEvent {
type: EventType.UPDATE_ORG;
metadata: {
name?: string;
slug?: string;
authEnforced?: boolean;
scimEnabled?: boolean;
defaultMembershipRoleSlug?: string;
enforceMfa?: boolean;
selectedMfaMethod?: string;
allowSecretSharingOutsideOrganization?: boolean;
bypassOrgAuthEnabled?: boolean;
userTokenExpiration?: string;
secretsProductEnabled?: boolean;
pkiProductEnabled?: boolean;
kmsProductEnabled?: boolean;
sshProductEnabled?: boolean;
scannerProductEnabled?: boolean;
shareSecretsProductEnabled?: boolean;
};
}
interface ProjectCreateEvent {
type: EventType.CREATE_PROJECT;
metadata: {
name: string;
slug?: string;
type: ProjectType;
};
}
interface ProjectUpdateEvent {
type: EventType.UPDATE_PROJECT;
metadata: {
name?: string;
description?: string;
autoCapitalization?: boolean;
hasDeleteProtection?: boolean;
slug?: string;
secretSharing?: boolean;
pitVersionLimit?: number;
auditLogsRetentionDays?: number;
};
}
interface ProjectDeleteEvent {
type: EventType.DELETE_PROJECT;
metadata: {
id: string;
name: string;
};
}
export type Event =
| GetSecretsEvent
| GetSecretEvent
@@ -2617,6 +3062,11 @@ export type Event =
| UpdateIdentityAwsAuthEvent
| GetIdentityAwsAuthEvent
| DeleteIdentityAwsAuthEvent
| LoginIdentityOciAuthEvent
| AddIdentityOciAuthEvent
| UpdateIdentityOciAuthEvent
| GetIdentityOciAuthEvent
| DeleteIdentityOciAuthEvent
| LoginIdentityAzureAuthEvent
| AddIdentityAzureAuthEvent
| DeleteIdentityAzureAuthEvent
@@ -2632,6 +3082,11 @@ export type Event =
| UpdateIdentityJwtAuthEvent
| GetIdentityJwtAuthEvent
| DeleteIdentityJwtAuthEvent
| LoginIdentityLdapAuthEvent
| AddIdentityLdapAuthEvent
| UpdateIdentityLdapAuthEvent
| GetIdentityLdapAuthEvent
| RevokeIdentityLdapAuthEvent
| CreateEnvironmentEvent
| GetEnvironmentEvent
| UpdateEnvironmentEvent
@@ -2675,6 +3130,7 @@ export type Event =
| IssueSshHostHostCert
| CreateCa
| GetCa
| GetCAs
| UpdateCa
| DeleteCa
| RenewCa
@@ -2685,12 +3141,15 @@ export type Event =
| ImportCaCert
| GetCaCrls
| IssueCert
| ImportCert
| SignCert
| GetCaCertificateTemplates
| GetCert
| DeleteCert
| RevokeCert
| GetCertBody
| GetCertPrivateKey
| GetCertBundle
| CreatePkiAlert
| GetPkiAlert
| UpdatePkiAlert
@@ -2702,6 +3161,15 @@ export type Event =
| GetPkiCollectionItems
| AddPkiCollectionItem
| DeletePkiCollectionItem
| CreatePkiSubscriber
| UpdatePkiSubscriber
| DeletePkiSubscriber
| GetPkiSubscriber
| IssuePkiSubscriberCert
| SignPkiSubscriberCert
| AutomatedRenewPkiSubscriberCert
| ListPkiSubscriberCerts
| GetSubscriberActiveCertBundle
| CreateKmsEvent
| UpdateKmsEvent
| DeleteKmsEvent
@@ -2723,8 +3191,8 @@ export type Event =
| UpdateSlackIntegration
| DeleteSlackIntegration
| GetSlackIntegration
| UpdateProjectSlackConfig
| GetProjectSlackConfig
| UpdateProjectWorkflowIntegrationConfig
| GetProjectWorkflowIntegrationConfig
| GetProjectSshConfig
| UpdateProjectSshConfig
| IntegrationSyncedEvent
@@ -2746,13 +3214,19 @@ export type Event =
| CreateProjectTemplateEvent
| UpdateProjectTemplateEvent
| DeleteProjectTemplateEvent
| ApplyProjectTemplateEvent
| GetAppConnectionsEvent
| GetAvailableAppConnectionsDetailsEvent
| GetAppConnectionEvent
| CreateAppConnectionEvent
| UpdateAppConnectionEvent
| DeleteAppConnectionEvent
| GetSshHostGroupEvent
| CreateSshHostGroupEvent
| UpdateSshHostGroupEvent
| DeleteSshHostGroupEvent
| GetSshHostGroupHostsEvent
| AddHostToSshHostGroupEvent
| RemoveHostFromSshHostGroupEvent
| CreateSharedSecretEvent
| DeleteSharedSecretEvent
| ReadSharedSecretEvent
@@ -2794,4 +3268,15 @@ export type Event =
| CreateSecretRotationEvent
| UpdateSecretRotationEvent
| DeleteSecretRotationEvent
| RotateSecretRotationEvent;
| RotateSecretRotationEvent
| MicrosoftTeamsWorkflowIntegrationCreateEvent
| MicrosoftTeamsWorkflowIntegrationDeleteEvent
| MicrosoftTeamsWorkflowIntegrationCheckInstallationStatusEvent
| MicrosoftTeamsWorkflowIntegrationGetTeamsEvent
| MicrosoftTeamsWorkflowIntegrationGetEvent
| MicrosoftTeamsWorkflowIntegrationListEvent
| MicrosoftTeamsWorkflowIntegrationUpdateEvent
| OrgUpdateEvent
| ProjectCreateEvent
| ProjectUpdateEvent
| ProjectDeleteEvent;

View File

@@ -7,6 +7,7 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { NotFoundError } from "@app/lib/errors";
import { TCertificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal";
import { expandInternalCa } from "@app/services/certificate-authority/certificate-authority-fns";
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TProjectDALFactory } from "@app/services/project/project-dal";
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
@@ -14,7 +15,7 @@ import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns
import { TGetCaCrlsDTO, TGetCrlById } from "./certificate-authority-crl-types";
type TCertificateAuthorityCrlServiceFactoryDep = {
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findByIdWithAssociatedCa">;
certificateAuthorityCrlDAL: Pick<TCertificateAuthorityCrlDALFactory, "find" | "findById">;
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
kmsService: Pick<TKmsServiceFactory, "decryptWithKmsKey" | "generateKmsKey">;
@@ -37,7 +38,8 @@ export const certificateAuthorityCrlServiceFactory = ({
const caCrl = await certificateAuthorityCrlDAL.findById(crlId);
if (!caCrl) throw new NotFoundError({ message: `CRL with ID '${crlId}' not found` });
const ca = await certificateAuthorityDAL.findById(caCrl.caId);
const ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(caCrl.caId);
if (!ca?.internalCa?.id) throw new NotFoundError({ message: `Internal CA with ID '${caCrl.caId}' not found` });
const keyId = await getProjectKmsCertificateKeyId({
projectId: ca.projectId,
@@ -54,7 +56,7 @@ export const certificateAuthorityCrlServiceFactory = ({
const crl = new x509.X509Crl(decryptedCrl);
return {
ca,
ca: expandInternalCa(ca),
caCrl,
crl: crl.rawData
};
@@ -64,8 +66,8 @@ export const certificateAuthorityCrlServiceFactory = ({
* Returns a list of CRL ids for CA with id [caId]
*/
const getCaCrls = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCaCrlsDTO) => {
const ca = await certificateAuthorityDAL.findById(caId);
if (!ca) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
const ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(caId);
if (!ca?.internalCa?.id) throw new NotFoundError({ message: `Internal CA with ID '${caId}' not found` });
const { permission } = await permissionService.getProjectPermission({
actor,
@@ -108,7 +110,7 @@ export const certificateAuthorityCrlServiceFactory = ({
);
return {
ca,
ca: expandInternalCa(ca),
crls: decryptedCrls
};
};

View File

@@ -6,7 +6,7 @@ import { isCertChainValid } from "@app/services/certificate/certificate-fns";
import { TCertificateAuthorityCertDALFactory } from "@app/services/certificate-authority/certificate-authority-cert-dal";
import { TCertificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal";
import { getCaCertChain, getCaCertChains } from "@app/services/certificate-authority/certificate-authority-fns";
import { TCertificateAuthorityServiceFactory } from "@app/services/certificate-authority/certificate-authority-service";
import { TInternalCertificateAuthorityServiceFactory } from "@app/services/certificate-authority/internal/internal-certificate-authority-service";
import { TCertificateTemplateDALFactory } from "@app/services/certificate-template/certificate-template-dal";
import { TCertificateTemplateServiceFactory } from "@app/services/certificate-template/certificate-template-service";
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
@@ -16,10 +16,10 @@ import { TLicenseServiceFactory } from "../license/license-service";
import { convertRawCertsToPkcs7 } from "./certificate-est-fns";
type TCertificateEstServiceFactoryDep = {
certificateAuthorityService: Pick<TCertificateAuthorityServiceFactory, "signCertFromCa">;
internalCertificateAuthorityService: Pick<TInternalCertificateAuthorityServiceFactory, "signCertFromCa">;
certificateTemplateService: Pick<TCertificateTemplateServiceFactory, "getEstConfiguration">;
certificateTemplateDAL: Pick<TCertificateTemplateDALFactory, "findById">;
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById" | "findByIdWithAssociatedCa">;
certificateAuthorityCertDAL: Pick<TCertificateAuthorityCertDALFactory, "find" | "findById">;
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
kmsService: Pick<TKmsServiceFactory, "decryptWithKmsKey" | "generateKmsKey">;
@@ -29,7 +29,7 @@ type TCertificateEstServiceFactoryDep = {
export type TCertificateEstServiceFactory = ReturnType<typeof certificateEstServiceFactory>;
export const certificateEstServiceFactory = ({
certificateAuthorityService,
internalCertificateAuthorityService,
certificateTemplateService,
certificateTemplateDAL,
certificateAuthorityCertDAL,
@@ -127,7 +127,7 @@ export const certificateEstServiceFactory = ({
});
}
const { certificate } = await certificateAuthorityService.signCertFromCa({
const { certificate } = await internalCertificateAuthorityService.signCertFromCa({
isInternal: true,
certificateTemplateId,
csr
@@ -188,7 +188,7 @@ export const certificateEstServiceFactory = ({
}
}
const { certificate } = await certificateAuthorityService.signCertFromCa({
const { certificate } = await internalCertificateAuthorityService.signCertFromCa({
isInternal: true,
certificateTemplateId,
csr
@@ -227,15 +227,15 @@ export const certificateEstServiceFactory = ({
});
}
const ca = await certificateAuthorityDAL.findById(certTemplate.caId);
if (!ca) {
const ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(certTemplate.caId);
if (!ca?.internalCa?.id) {
throw new NotFoundError({
message: `Certificate Authority with ID '${certTemplate.caId}' not found`
message: `Internal Certificate Authority with ID '${certTemplate.caId}' not found`
});
}
const { caCert, caCertChain } = await getCaCertChain({
caCertId: ca.activeCaCertId as string,
caCertId: ca.internalCa.activeCaCertId as string,
certificateAuthorityDAL,
certificateAuthorityCertDAL,
projectDAL,

View File

@@ -24,8 +24,16 @@ export const verifyHostInputValidity = async (host: string, isGateway = false) =
if (net.isIPv4(el)) {
exclusiveIps.push(el);
} else {
const resolvedIps = await dns.resolve4(el);
exclusiveIps.push(...resolvedIps);
try {
const resolvedIps = await dns.resolve4(el);
exclusiveIps.push(...resolvedIps);
} catch (error) {
// only try lookup if not found
if ((error as { code: string })?.code !== "ENOTFOUND") throw error;
const resolvedIps = (await dns.lookup(el, { all: true, family: 4 })).map(({ address }) => address);
exclusiveIps.push(...resolvedIps);
}
}
}
}
@@ -38,8 +46,16 @@ export const verifyHostInputValidity = async (host: string, isGateway = false) =
if (normalizedHost === "localhost" || normalizedHost === "host.docker.internal") {
throw new BadRequestError({ message: "Invalid db host" });
}
const resolvedIps = await dns.resolve4(host);
inputHostIps.push(...resolvedIps);
try {
const resolvedIps = await dns.resolve4(host);
inputHostIps.push(...resolvedIps);
} catch (error) {
// only try lookup if not found
if ((error as { code: string })?.code !== "ENOTFOUND") throw error;
const resolvedIps = (await dns.lookup(host, { all: true, family: 4 })).map(({ address }) => address);
inputHostIps.push(...resolvedIps);
}
}
if (!isGateway && !(appCfg.DYNAMIC_SECRET_ALLOW_INTERNAL_IP || appCfg.ALLOW_INTERNAL_IP_CONNECTIONS)) {

View File

@@ -17,7 +17,8 @@ import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-fold
import { TDynamicSecretLeaseDALFactory } from "../dynamic-secret-lease/dynamic-secret-lease-dal";
import { TDynamicSecretLeaseQueueServiceFactory } from "../dynamic-secret-lease/dynamic-secret-lease-queue";
import { TProjectGatewayDALFactory } from "../gateway/project-gateway-dal";
import { TGatewayDALFactory } from "../gateway/gateway-dal";
import { OrgPermissionGatewayActions, OrgPermissionSubjects } from "../permission/org-permission";
import { TDynamicSecretDALFactory } from "./dynamic-secret-dal";
import {
DynamicSecretStatus,
@@ -44,9 +45,9 @@ type TDynamicSecretServiceFactoryDep = {
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
folderDAL: Pick<TSecretFolderDALFactory, "findBySecretPath" | "findBySecretPathMultiEnv">;
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">;
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
projectGatewayDAL: Pick<TProjectGatewayDALFactory, "findOne">;
gatewayDAL: Pick<TGatewayDALFactory, "findOne" | "find">;
resourceMetadataDAL: Pick<TResourceMetadataDALFactory, "insertMany" | "delete">;
};
@@ -62,7 +63,7 @@ export const dynamicSecretServiceFactory = ({
dynamicSecretQueueService,
projectDAL,
kmsService,
projectGatewayDAL,
gatewayDAL,
resourceMetadataDAL
}: TDynamicSecretServiceFactoryDep) => {
const create = async ({
@@ -117,15 +118,31 @@ export const dynamicSecretServiceFactory = ({
const inputs = await selectedProvider.validateProviderInputs(provider.inputs);
let selectedGatewayId: string | null = null;
if (inputs && typeof inputs === "object" && "projectGatewayId" in inputs && inputs.projectGatewayId) {
const projectGatewayId = inputs.projectGatewayId as string;
if (inputs && typeof inputs === "object" && "gatewayId" in inputs && inputs.gatewayId) {
const gatewayId = inputs.gatewayId as string;
const projectGateway = await projectGatewayDAL.findOne({ id: projectGatewayId, projectId });
if (!projectGateway)
const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: actorOrgId });
if (!gateway) {
throw new NotFoundError({
message: `Project gateway with ${projectGatewayId} not found`
message: `Gateway with ID ${gatewayId} not found`
});
selectedGatewayId = projectGateway.id;
}
const { permission: orgPermission } = await permissionService.getOrgPermission(
actor,
actorId,
gateway.orgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(orgPermission).throwUnlessCan(
OrgPermissionGatewayActions.AttachGateways,
OrgPermissionSubjects.Gateway
);
selectedGatewayId = gateway.id;
}
const isConnected = await selectedProvider.validateConnection(provider.inputs);
@@ -146,7 +163,7 @@ export const dynamicSecretServiceFactory = ({
defaultTTL,
folderId: folder.id,
name,
projectGatewayId: selectedGatewayId
gatewayId: selectedGatewayId
},
tx
);
@@ -255,20 +272,30 @@ export const dynamicSecretServiceFactory = ({
const updatedInput = await selectedProvider.validateProviderInputs(newInput);
let selectedGatewayId: string | null = null;
if (
updatedInput &&
typeof updatedInput === "object" &&
"projectGatewayId" in updatedInput &&
updatedInput?.projectGatewayId
) {
const projectGatewayId = updatedInput.projectGatewayId as string;
if (updatedInput && typeof updatedInput === "object" && "gatewayId" in updatedInput && updatedInput?.gatewayId) {
const gatewayId = updatedInput.gatewayId as string;
const projectGateway = await projectGatewayDAL.findOne({ id: projectGatewayId, projectId });
if (!projectGateway)
const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: actorOrgId });
if (!gateway) {
throw new NotFoundError({
message: `Project gateway with ${projectGatewayId} not found`
message: `Gateway with ID ${gatewayId} not found`
});
selectedGatewayId = projectGateway.id;
}
const { permission: orgPermission } = await permissionService.getOrgPermission(
actor,
actorId,
gateway.orgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(orgPermission).throwUnlessCan(
OrgPermissionGatewayActions.AttachGateways,
OrgPermissionSubjects.Gateway
);
selectedGatewayId = gateway.id;
}
const isConnected = await selectedProvider.validateConnection(newInput);
@@ -284,7 +311,7 @@ export const dynamicSecretServiceFactory = ({
defaultTTL,
name: newName ?? name,
status: null,
projectGatewayId: selectedGatewayId
gatewayId: selectedGatewayId
},
tx
);

View File

@@ -6,6 +6,7 @@ import { AwsIamProvider } from "./aws-iam";
import { AzureEntraIDProvider } from "./azure-entra-id";
import { CassandraProvider } from "./cassandra";
import { ElasticSearchProvider } from "./elastic-search";
import { KubernetesProvider } from "./kubernetes";
import { LdapProvider } from "./ldap";
import { DynamicSecretProviders, TDynamicProviderFns } from "./models";
import { MongoAtlasProvider } from "./mongo-atlas";
@@ -18,7 +19,7 @@ import { SqlDatabaseProvider } from "./sql-database";
import { TotpProvider } from "./totp";
type TBuildDynamicSecretProviderDTO = {
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTls">;
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">;
};
export const buildDynamicSecretProviders = ({
@@ -38,5 +39,6 @@ export const buildDynamicSecretProviders = ({
[DynamicSecretProviders.SapHana]: SapHanaProvider(),
[DynamicSecretProviders.Snowflake]: SnowflakeProvider(),
[DynamicSecretProviders.Totp]: TotpProvider(),
[DynamicSecretProviders.SapAse]: SapAseProvider()
[DynamicSecretProviders.SapAse]: SapAseProvider(),
[DynamicSecretProviders.Kubernetes]: KubernetesProvider({ gatewayService })
});

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