Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nixify + port to GHC 9.2 #3

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
bf82891
wip: nixify
srid Jun 5, 2023
c70887d
Port to GHC 9.2
srid Jun 5, 2023
272beca
WIP: Add process-compose configuration
srid Jun 21, 2023
f92aa72
Add passetto process itself
srid Jun 21, 2023
63d512f
Add overlay to flake
srid Jun 21, 2023
b49508d
create_schema.sql: Add sample values (from nammayatri)
srid Jun 27, 2023
01a59da
Add Jenkinsfile
srid Oct 13, 2023
806f6f1
Configure `pg_hba.conf` (#1)
shivaraj-bh Oct 15, 2023
8fd1b2b
jenkins: disable build on m1 mac
srid Oct 15, 2023
cfa8e72
Added initialScript option to passetto
rsrohitsingh682 Dec 12, 2023
35219be
Merge pull request #4 from rsrohitsingh682/add/exposeInitialScript
srid Dec 12, 2023
222ab60
Update initialScripts to initialDumps in passetto (#5)
rsrohitsingh682 Jan 12, 2024
f170d2a
Exposed an option to configure ports for Passetto-db and Passetto-server
rsrohitsingh682 Jan 12, 2024
0c501e3
Added extraDbSettings and removed initialDumps as it can be used with…
rsrohitsingh682 Jan 12, 2024
5535db1
Removed the default port from extraDbSettings and updated description
rsrohitsingh682 Jan 12, 2024
355a910
Fixed CI by adding converting port to string
rsrohitsingh682 Jan 12, 2024
b12a0a8
Merge pull request #6 from rsrohitsingh682/expose-option-for-port
shivaraj-bh Jan 12, 2024
af7847a
use schemas; environment.PORT belongs to passetto-service
shivaraj-bh Jan 13, 2024
141609f
flake.lock: update services-flake
shivaraj-bh Jan 16, 2024
5381386
Merge pull request #7 from nammayatri/postgres-schemas
shivaraj-bh Jan 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ dist-*

## Acid-state
state/

# Nix
result
result-*
.direnv
/data
44 changes: 44 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
pipeline {
agent none
options {
parallelsAlwaysFailFast()
}
stages {
stage ('Matrix') {
matrix {
agent {
label "${SYSTEM}"
}
axes {
axis {
name 'SYSTEM'
// passetto doesn't build on m1 mac; https://github.com/juspay/passetto/issues/2
values 'x86_64-linux', 'x86_64-darwin'
}
}
stages {
stage ('Cachix setup') {
steps {
cachixUse "nammayatri"
}
}
stage ('Nix Build All') {
steps {
nixCI system: env.SYSTEM
}
}
stage ('Cachix push') {
when {
anyOf {
branch 'main'
}
}
steps {
cachixPush "nammayatri"
}
}
}
}
}
}
}
4 changes: 4 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
packages:
client
core
service
112 changes: 112 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
haskell-flake.url = "github:srid/haskell-flake";

process-compose-flake.url = "github:Platonic-Systems/process-compose-flake";
services-flake.url = "github:juspay/services-flake";
};
outputs = inputs@{ nixpkgs, flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } ({ self, ... }: {
systems = nixpkgs.lib.systems.flakeExposed;
imports = [
inputs.flake-parts.flakeModules.easyOverlay
inputs.haskell-flake.flakeModule
inputs.process-compose-flake.flakeModule
];

perSystem = { config, self', pkgs, system, lib, ... }: {
haskellProjects.default = { };

overlayAttrs = {
passetto-service = lib.getBin self'.packages.passetto-service;
};

process-compose."default" = {
imports = [
inputs.services-flake.processComposeModules.default
self.processComposeModules.default
];
services.passetto = {
enable = true;
package = lib.getBin self'.packages.passetto-service;
pgweb.enable = true;
};
};
};

flake.processComposeModules.default = ./process-compose.nix;
});
}
95 changes: 95 additions & 0 deletions process-compose.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{ config, pkgs, lib, ... }:
let
srvname = "passetto";
dbName = "passetto";
userName = "passetto";
pgcfg = config.services.postgres."${srvname}-db";
in
{
options = {
services.passetto = lib.mkOption {
type = lib.types.submodule {
options = {
enable = lib.mkEnableOption "Enable passetto service";
package = lib.mkPackageOption pkgs.haskellPackages "passetto-service" { };
pgurl = lib.mkOption {
type = lib.types.str;
default = "postgresql://${userName}@${pgcfg.listen_addresses}:${builtins.toString pgcfg.port}/${dbName}";
description = "Postgres connection string";
};
pgweb.enable = lib.mkEnableOption "Enable pgweb on passetto db";
port = lib.mkOption {
type = lib.types.port;
default = 8012;
description = ''
The TCP port to accept connections.
'';
};
extraDbSettings = lib.mkOption {
type = lib.types.deferredModule;
default = { };
description = ''
Extra Postgres database settings.
'';
};
};
};
};
};
config =
let
cfg = config.services.passetto;
in
lib.mkIf cfg.enable {
services.postgres."${srvname}-db" = {
imports = [ cfg.extraDbSettings ];
enable = true;
port = lib.mkDefault 8012;
listen_addresses = "127.0.0.1";
hbaConf = [
# Equivalent to `POSTGRES_INITDB_ARGS = "--auth=scram-sha-256";`, sets the auth for all users
# connecting through unix sockets.
{ type = "local"; database = "all"; user = "all"; address = ""; method = "scram-sha-256"; }
# Equivalent to `POSTGRES_HOST_AUTH_METHOD = "scram-sha-256";`, sets the auth for all users
# connecting through loopback ipv4/v6
{ type = "host"; database = "all"; user = "all"; address = "127.0.0.1/32"; method = "scram-sha-256"; }
{ type = "host"; database = "all"; user = "all"; address = "::1/128"; method = "scram-sha-256"; }
];
initialScript.before = ''
CREATE ROLE ${userName} SUPERUSER;
ALTER ROLE ${userName} WITH LOGIN;
'';
initialDatabases = [
{
name = dbName;
schemas = [ ./service/pgsql/create_schema.sql ];
}
];
};
settings = {
processes = {
"${srvname}-pgweb" = lib.mkIf cfg.pgweb.enable {
environment.PGWEB_DATABASE_URL = cfg.pgurl;
command = pkgs.pgweb;
depends_on."${srvname}-db".condition = "process_healthy";
};
passetto-service = { name, ... }: {
environment.PASSETTO_PG_BACKEND_CONN_STRING = cfg.pgurl;
environment.PORT = builtins.toString cfg.port;
depends_on."${srvname}-db".condition = "process_healthy";
command = pkgs.writeShellApplication {
inherit name;
text = ''
export PATH=${cfg.package}/bin:$PATH
set -x
password="1"
keys=3
passetto-init $password $keys
MASTER_PASSWORD=$password passetto-server
'';
};
};
};
};
};
}
3 changes: 2 additions & 1 deletion service/app/init/KeysDb.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import System.Environment (getArgs)

import Passetto.Crypto (Password(..), encode)
import Passetto.Db (openDb, appendDb, readAndDecryptDb)
import qualified Crypto.Saltine.Core.Box as Box

main :: IO ()
main = do
db <- openDb
let
doit [p, nstr]
| Just n <- readMaybe nstr = appendDb (mkPwd p) n db >>= either quit (const $ putTextLn "Ok")
doit [p] = readAndDecryptDb (mkPwd p) db >>= either quit (mapM_ (print . bimap encode encode) . toList)
doit [p] = readAndDecryptDb (mkPwd p) db >>= either quit (mapM_ (print . bimap encode encode . (Box.secretKey &&& Box.publicKey)) . toList)
doit _ = putStrLn @String logo
getArgs >>= doit
where
Expand Down
3 changes: 2 additions & 1 deletion service/app/init/KeysDbInteractive.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import System.Environment (getArgs)

import Passetto.Crypto (encode)
import Passetto.Db (openDb, appendDbInteractive, readAndDecryptDbInteractive, changePasswordInteractive)
import qualified Crypto.Saltine.Core.Box as Box

main :: IO ()
main = do
db <- openDb
let
doit ["addkeys", nstr]
| Just n <- readMaybe nstr = appendDbInteractive n db >>= print
doit ["dump"] = readAndDecryptDbInteractive db >>= either print (mapM_ (print . bimap encode encode) . toList)
doit ["dump"] = readAndDecryptDbInteractive db >>= either print (mapM_ (print . bimap encode encode . (Box.secretKey &&& Box.publicKey)) . toList)
doit ["newpass"] = changePasswordInteractive db >>= print
doit _ = putStrLn @String logo
getArgs >>= doit
Expand Down
5 changes: 5 additions & 0 deletions service/pgsql/create_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ TABLESPACE pg_default;

ALTER TABLE "Passetto"."Keys"
OWNER to passetto;

INSERT INTO "Passetto"."Master" (key) values (decode('00000000000000302d476de40bb08e3d1b42bf232b7aae8a98609345cb5bc479e8a587065535806cc40c2113d333003202cb13f1f707583e0000000000000018bfe4d57672c4ca94a8ea6899b51c717578a518e346ad35fb00000000000000107df9a9cc38ee3e56f00a85c18e9e4a50', 'hex'));
INSERT INTO "Passetto"."Keys" (encryptedKeyPair) values(decode('0000000000000060876de70043e785ec2ab412a5e1cb10e5dd1ebcbf3f2342b8cfd58d56ae4b26e8843dbb181c4966ffb17c5023b1e8781d44c45f62bc83f5b54eb2541ae1cbea13dbe1ebe1d6fd981b1c24bb3d5726480682e64467d16124eb05818ef6e00d1f910000000000000018f7a67d7cd4578a2fa81555ac32b1caa41003770cc3a11be0', 'hex'));
INSERT INTO "Passetto"."Keys" (encryptedKeyPair) values(decode('00000000000000604a15b9e19523d67e2e92563988988d05370ee9351aee801b3b39a7189697af47e4c05c30801fd20166294ed4cc8ac4196316fbbe19e918597141a2a3331ac0aa6bba41cc6a27a9f637678d4bc3227d053f47c5eb8df2899069c768e0c3ad0f3e0000000000000018e5772b2fbd2c1cef9a2fd90d4abb823e3cb29600b538aaac', 'hex'));
INSERT INTO "Passetto"."Keys" (encryptedKeyPair) values(decode('000000000000006055def0dc30180d82833b2ca2491e17e4f38730d539b30145d17eae8544a41c4eda977d8c14af80f1a7ccd2dba076210869d5de2b884006f9f096363c1061ce98098d95d44d8d0e429191292b0a210468989cef34da4f6d4ce28f8b7e3c56a1d30000000000000018fbe28c341465b1de7871732e88767a0087364319446a3d9c', 'hex'));
9 changes: 5 additions & 4 deletions service/src/Passetto/Crypto.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import qualified Data.X509 as X509

import qualified Data.Binary as B
import qualified Data.ByteString.Lazy as LBS (fromStrict, toStrict)
import Crypto.Saltine.Internal.SecretBox (secretbox_keybytes)

-- Utils, move elsewhere
instance B.Binary Box.SecretKey
Expand Down Expand Up @@ -118,7 +119,7 @@ decryptMasterKey (EncryptedKey{..}, emkKdfSalt) password =
-- Derives a key for encrypting master.
mkEncryptionKey :: ByteString -> Password -> SecretBox.Key
mkEncryptionKey salt (Password pw) = do
let skBs = Argon2.hash keyDerivationOptions pw salt Sizes.secretBoxKey
let skBs = Argon2.hash keyDerivationOptions pw salt secretbox_keybytes
& throwCryptoError -- fails only when parameters are incorrect
Saltine.decode skBs ?: error "Illegal secret box key size"

Expand All @@ -132,18 +133,18 @@ keyDerivationOptions = Argon2.defaultOptions
-- | Encrypt a key for further saving in storage.
encryptKey :: MonadIO m => SecretBox.Key -> Box.Keypair -> m EncryptedKey
encryptKey mk k =
liftIO $ encryptKeyInternal mk (encodeStrict k)
liftIO $ encryptKeyInternal mk (encodeStrict . (Box.secretKey &&& Box.publicKey) $ k)

decryptKey :: SecretBox.Key -> EncryptedKey -> Maybe Box.Keypair
decryptKey mk EncryptedKey{..} = decodeStrict <$> SecretBox.secretboxOpen mk emkNonce emkSecret
decryptKey mk EncryptedKey{..} = uncurry Box.Keypair . decodeStrict <$> SecretBox.secretboxOpen mk emkNonce emkSecret

-- | Encrypt a user message.
encrypt :: MonadIO m => Box.PublicKey -> ByteString -> m ByteString
encrypt k msg = liftIO $ Box.boxSeal k msg

-- | Decrypt a user message.
decrypt :: Box.Keypair -> ByteString -> Maybe ByteString
decrypt (kSecret, kPublic) enc = Box.boxSealOpen kPublic kSecret enc
decrypt pair = Box.boxSealOpen (Box.publicKey pair) (Box.secretKey pair)

-- | Dump a public key into X.509 certificate.
publicToPem :: Box.PublicKey -> LByteString
Expand Down
Loading