Skip to content

Commit 2d99a0a

Browse files
saurawwSaurav Suman
andauthored
feat: secrets support for functions/webhooks (#773)
* feat: secrets support for functions/webhooks * fix: added previous_master_key fallback to prevent failures while rotating --------- Co-authored-by: Saurav Suman <[email protected]>
1 parent 5e642fb commit 2d99a0a

File tree

279 files changed

+24710
-662
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

279 files changed

+24710
-662
lines changed

.env.example

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,16 @@ AUTH_PROVIDER=DISABLED
3737
# OIDC_ORG_ISSUER_ENDPOINT_FORMAT="http://localhost:8081/realms/<organisation>"
3838
AUTH_Z_PROVIDER=DISABLED
3939
WORKER_ID=1
40-
ENCRYPTED_KEYS="" # Used for webhook secrets, API keys, etc.
41-
# ENCRYPTED_KEYS="SERVICE1_API_KEY,SERVICE2_API_KEY"
40+
# MASTER_ENCRYPTION_KEY - add this for enabling secrets in local
4241

4342
################################################
4443
## Following values are to be set in KMS and not directly in ENV
4544
#
4645
# DB_PASSWORD
4746
# SUPERPOSITION_TOKEN
4847
# OIDC_CLIENT_SECRET - if using OIDC as auth provider
48+
# MASTER_ENCRYPTION_KEY - for using secrets
49+
# PREVIOUS_MASTER_ENCRYPTION_KEY - needed for rotating secrets
4950
#
5051
# also include the keys in KMS which have been mentioned in ENCRYPTED_KEYS
5152
#

Cargo.lock

Lines changed: 115 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ reqwest = { version = "0.11.18", features = ["json"] }
7070
rs-snowflake = "0.6.0"
7171
serde = { version = "^1", features = ["derive"] }
7272
serde_json = { version = "1.0.140" }
73+
secrecy = "0.10"
7374
strum = "0.25"
7475
strum_macros = "0.25"
7576
toml = { version = "0.8.8", features = ["preserve_order"] }
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
module Io.Superposition.Command.CreateSecret (
2+
CreateSecretError (..),
3+
createSecret
4+
) where
5+
import qualified Data.Aeson
6+
import qualified Data.Maybe
7+
import qualified Data.Text
8+
import qualified GHC.Generics
9+
import qualified GHC.Show
10+
import qualified Io.Superposition.Model.CreateSecretInput
11+
import qualified Io.Superposition.Model.CreateSecretOutput
12+
import qualified Io.Superposition.Model.InternalServerError
13+
import qualified Io.Superposition.SuperpositionClient
14+
import qualified Io.Superposition.Utility
15+
16+
data CreateSecretError =
17+
InternalServerError Io.Superposition.Model.InternalServerError.InternalServerError
18+
| BuilderError Data.Text.Text
19+
| DeSerializationError Io.Superposition.Utility.HttpMetadata Data.Text.Text
20+
| UnexpectedError (Data.Maybe.Maybe Io.Superposition.Utility.HttpMetadata) Data.Text.Text
21+
deriving (GHC.Generics.Generic, GHC.Show.Show)
22+
23+
instance Data.Aeson.ToJSON CreateSecretError
24+
instance Io.Superposition.Utility.OperationError CreateSecretError where
25+
mkBuilderError = BuilderError
26+
mkDeSerializationError = DeSerializationError
27+
mkUnexpectedError = UnexpectedError
28+
29+
getErrorParser status
30+
| status == (Io.Superposition.Utility.expectedStatus @Io.Superposition.Model.InternalServerError.InternalServerError) = Just (fmap InternalServerError (Io.Superposition.Utility.responseParser @Io.Superposition.Model.InternalServerError.InternalServerError))
31+
| otherwise = Nothing
32+
33+
34+
createSecret :: Io.Superposition.SuperpositionClient.SuperpositionClient -> Io.Superposition.Model.CreateSecretInput.CreateSecretInputBuilder () -> IO (Either CreateSecretError Io.Superposition.Model.CreateSecretOutput.CreateSecretOutput)
35+
createSecret client builder =
36+
let endpoint = Io.Superposition.SuperpositionClient.endpointUri client
37+
manager = Io.Superposition.SuperpositionClient.httpManager client
38+
auth = Io.Superposition.SuperpositionClient.getAuth client
39+
in Io.Superposition.Utility.runOperation endpoint manager auth (Io.Superposition.Model.CreateSecretInput.build builder)
40+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module Io.Superposition.Command.DeleteSecret (
2+
DeleteSecretError (..),
3+
deleteSecret
4+
) where
5+
import qualified Data.Aeson
6+
import qualified Data.Maybe
7+
import qualified Data.Text
8+
import qualified GHC.Generics
9+
import qualified GHC.Show
10+
import qualified Io.Superposition.Model.DeleteSecretInput
11+
import qualified Io.Superposition.Model.DeleteSecretOutput
12+
import qualified Io.Superposition.Model.InternalServerError
13+
import qualified Io.Superposition.Model.ResourceNotFound
14+
import qualified Io.Superposition.SuperpositionClient
15+
import qualified Io.Superposition.Utility
16+
17+
data DeleteSecretError =
18+
ResourceNotFound Io.Superposition.Model.ResourceNotFound.ResourceNotFound
19+
| InternalServerError Io.Superposition.Model.InternalServerError.InternalServerError
20+
| BuilderError Data.Text.Text
21+
| DeSerializationError Io.Superposition.Utility.HttpMetadata Data.Text.Text
22+
| UnexpectedError (Data.Maybe.Maybe Io.Superposition.Utility.HttpMetadata) Data.Text.Text
23+
deriving (GHC.Generics.Generic, GHC.Show.Show)
24+
25+
instance Data.Aeson.ToJSON DeleteSecretError
26+
instance Io.Superposition.Utility.OperationError DeleteSecretError where
27+
mkBuilderError = BuilderError
28+
mkDeSerializationError = DeSerializationError
29+
mkUnexpectedError = UnexpectedError
30+
31+
getErrorParser status
32+
| status == (Io.Superposition.Utility.expectedStatus @Io.Superposition.Model.ResourceNotFound.ResourceNotFound) = Just (fmap ResourceNotFound (Io.Superposition.Utility.responseParser @Io.Superposition.Model.ResourceNotFound.ResourceNotFound))
33+
| status == (Io.Superposition.Utility.expectedStatus @Io.Superposition.Model.InternalServerError.InternalServerError) = Just (fmap InternalServerError (Io.Superposition.Utility.responseParser @Io.Superposition.Model.InternalServerError.InternalServerError))
34+
| otherwise = Nothing
35+
36+
37+
deleteSecret :: Io.Superposition.SuperpositionClient.SuperpositionClient -> Io.Superposition.Model.DeleteSecretInput.DeleteSecretInputBuilder () -> IO (Either DeleteSecretError Io.Superposition.Model.DeleteSecretOutput.DeleteSecretOutput)
38+
deleteSecret client builder =
39+
let endpoint = Io.Superposition.SuperpositionClient.endpointUri client
40+
manager = Io.Superposition.SuperpositionClient.httpManager client
41+
auth = Io.Superposition.SuperpositionClient.getAuth client
42+
in Io.Superposition.Utility.runOperation endpoint manager auth (Io.Superposition.Model.DeleteSecretInput.build builder)
43+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module Io.Superposition.Command.GetSecret (
2+
GetSecretError (..),
3+
getSecret
4+
) where
5+
import qualified Data.Aeson
6+
import qualified Data.Maybe
7+
import qualified Data.Text
8+
import qualified GHC.Generics
9+
import qualified GHC.Show
10+
import qualified Io.Superposition.Model.GetSecretInput
11+
import qualified Io.Superposition.Model.GetSecretOutput
12+
import qualified Io.Superposition.Model.InternalServerError
13+
import qualified Io.Superposition.Model.ResourceNotFound
14+
import qualified Io.Superposition.SuperpositionClient
15+
import qualified Io.Superposition.Utility
16+
17+
data GetSecretError =
18+
ResourceNotFound Io.Superposition.Model.ResourceNotFound.ResourceNotFound
19+
| InternalServerError Io.Superposition.Model.InternalServerError.InternalServerError
20+
| BuilderError Data.Text.Text
21+
| DeSerializationError Io.Superposition.Utility.HttpMetadata Data.Text.Text
22+
| UnexpectedError (Data.Maybe.Maybe Io.Superposition.Utility.HttpMetadata) Data.Text.Text
23+
deriving (GHC.Generics.Generic, GHC.Show.Show)
24+
25+
instance Data.Aeson.ToJSON GetSecretError
26+
instance Io.Superposition.Utility.OperationError GetSecretError where
27+
mkBuilderError = BuilderError
28+
mkDeSerializationError = DeSerializationError
29+
mkUnexpectedError = UnexpectedError
30+
31+
getErrorParser status
32+
| status == (Io.Superposition.Utility.expectedStatus @Io.Superposition.Model.ResourceNotFound.ResourceNotFound) = Just (fmap ResourceNotFound (Io.Superposition.Utility.responseParser @Io.Superposition.Model.ResourceNotFound.ResourceNotFound))
33+
| status == (Io.Superposition.Utility.expectedStatus @Io.Superposition.Model.InternalServerError.InternalServerError) = Just (fmap InternalServerError (Io.Superposition.Utility.responseParser @Io.Superposition.Model.InternalServerError.InternalServerError))
34+
| otherwise = Nothing
35+
36+
37+
getSecret :: Io.Superposition.SuperpositionClient.SuperpositionClient -> Io.Superposition.Model.GetSecretInput.GetSecretInputBuilder () -> IO (Either GetSecretError Io.Superposition.Model.GetSecretOutput.GetSecretOutput)
38+
getSecret client builder =
39+
let endpoint = Io.Superposition.SuperpositionClient.endpointUri client
40+
manager = Io.Superposition.SuperpositionClient.httpManager client
41+
auth = Io.Superposition.SuperpositionClient.getAuth client
42+
in Io.Superposition.Utility.runOperation endpoint manager auth (Io.Superposition.Model.GetSecretInput.build builder)
43+

0 commit comments

Comments
 (0)