From a792f43eaae0ec2cd30db2ea3308deded7a1a935 Mon Sep 17 00:00:00 2001 From: patlo-iog Date: Mon, 6 Nov 2023 11:39:34 +0700 Subject: [PATCH] fix: check for active RLS on db application user (#775) Signed-off-by: Pat Losoponkul --- .../connect/sql/repository/Migrations.scala | 19 +++++++++++++++++++ .../core/service/MockCredentialService.scala | 2 +- .../pollux/sql/repository/Migrations.scala | 19 +++++++++++++++++++ .../io/iohk/atala/agent/server/Main.scala | 4 ++++ .../io/iohk/atala/agent/server/Modules.scala | 1 - .../agent/server/http/ZHttpEndpoints.scala | 1 - .../atala/agent/server/sql/Migrations.scala | 19 +++++++++++++++++++ 7 files changed, 62 insertions(+), 3 deletions(-) diff --git a/connect/lib/sql-doobie/src/main/scala/io/iohk/atala/connect/sql/repository/Migrations.scala b/connect/lib/sql-doobie/src/main/scala/io/iohk/atala/connect/sql/repository/Migrations.scala index 1c5860347d..eeaf4dd70f 100644 --- a/connect/lib/sql-doobie/src/main/scala/io/iohk/atala/connect/sql/repository/Migrations.scala +++ b/connect/lib/sql-doobie/src/main/scala/io/iohk/atala/connect/sql/repository/Migrations.scala @@ -3,7 +3,9 @@ package io.iohk.atala.connect.sql.repository import doobie.* import doobie.implicits.* import doobie.util.transactor.Transactor +import io.iohk.atala.shared.db.ContextAwareTask import io.iohk.atala.shared.db.DbConfig +import io.iohk.atala.shared.db.Implicits.* import org.flywaydb.core.Flyway import zio.* import zio.interop.catz.* @@ -35,6 +37,23 @@ object Migrations { val layer: URLayer[DbConfig, Migrations] = ZLayer.fromFunction(Migrations.apply _) + /** Fail if the RLS is not enabled from a sample table */ + def validateRLS: RIO[Transactor[ContextAwareTask], Unit] = { + val cxnIO = sql""" + | SELECT row_security_active('public.connection_records'); + """.stripMargin + .query[Boolean] + .unique + + for { + xa <- ZIO.service[Transactor[ContextAwareTask]] + isRlsActive <- cxnIO.transactWithoutContext(xa) + _ <- ZIO + .fail(Exception("The RLS policy is not active for Connect DB application user")) + .unless(isRlsActive) + } yield () + } + def initDbPrivileges(appUser: String): RIO[Transactor[Task], Unit] = { val cxnIO = for { _ <- doobie.free.connection.createStatement.map { stm => diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/MockCredentialService.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/MockCredentialService.scala index c68cf44984..b3013f4745 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/MockCredentialService.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/MockCredentialService.scala @@ -6,7 +6,7 @@ import io.iohk.atala.mercury.model.DidId import io.iohk.atala.mercury.protocol.issuecredential.{IssueCredential, OfferCredential, RequestCredential} import io.iohk.atala.pollux.core.model.error.CredentialServiceError import io.iohk.atala.pollux.core.model.{DidCommID, IssueCredentialRecord} -import io.iohk.atala.pollux.vc.jwt.{Issuer, W3cCredentialPayload} +import io.iohk.atala.pollux.vc.jwt.W3cCredentialPayload import io.iohk.atala.prism.crypto.MerkleInclusionProof import io.iohk.atala.shared.models.WalletAccessContext import zio.mock.{Mock, Proxy} diff --git a/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/Migrations.scala b/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/Migrations.scala index d8938e8511..cac7549e18 100644 --- a/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/Migrations.scala +++ b/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/Migrations.scala @@ -3,7 +3,9 @@ package io.iohk.atala.pollux.sql.repository import doobie.* import doobie.implicits.* import doobie.util.transactor.Transactor +import io.iohk.atala.shared.db.ContextAwareTask import io.iohk.atala.shared.db.DbConfig +import io.iohk.atala.shared.db.Implicits.* import org.flywaydb.core.Flyway import zio.* import zio.interop.catz.* @@ -36,6 +38,23 @@ object Migrations { val layer: URLayer[DbConfig, Migrations] = ZLayer.fromFunction(Migrations.apply _) + /** Fail if the RLS is not enabled from a sample table */ + def validateRLS: RIO[Transactor[ContextAwareTask], Unit] = { + val cxnIO = sql""" + | SELECT row_security_active('public.credential_schema'); + """.stripMargin + .query[Boolean] + .unique + + for { + xa <- ZIO.service[Transactor[ContextAwareTask]] + isRlsActive <- cxnIO.transactWithoutContext(xa) + _ <- ZIO + .fail(Exception("The RLS policy is not active for Pollux DB application user")) + .unless(isRlsActive) + } yield () + } + def initDbPrivileges(appUser: String): RIO[Transactor[Task], Unit] = { val cxnIO = for { _ <- doobie.free.connection.createStatement.map { stm => diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Main.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Main.scala index 526edf6096..c12ec5f452 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Main.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Main.scala @@ -78,6 +78,10 @@ object MainApp extends ZIOAppDefault { _ <- ZIO.serviceWithZIO[PolluxMigrations](_.migrate) _ <- ZIO.serviceWithZIO[ConnectMigrations](_.migrate) _ <- ZIO.serviceWithZIO[AgentMigrations](_.migrate) + _ <- ZIO.logInfo("Running post-migration RLS checks for DB application users") + _ <- PolluxMigrations.validateRLS.provide(RepoModule.polluxContextAwareTransactorLayer) + _ <- ConnectMigrations.validateRLS.provide(RepoModule.connectContextAwareTransactorLayer) + _ <- AgentMigrations.validateRLS.provide(RepoModule.agentContextAwareTransactorLayer) } yield () override def run: ZIO[Any, Throwable, Unit] = { diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Modules.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Modules.scala index 38d4836efc..5f0ad2117d 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Modules.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/Modules.scala @@ -23,7 +23,6 @@ import io.iohk.atala.agent.walletapi.vault.{ VaultWalletSecretStorage } import io.iohk.atala.castor.core.service.DIDService -import io.iohk.atala.iam.authentication.DefaultAuthenticator import io.iohk.atala.iam.authentication.admin.AdminApiKeyAuthenticator import io.iohk.atala.iam.authentication.admin.AdminApiKeyAuthenticatorImpl import io.iohk.atala.iam.authentication.admin.AdminConfig diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/ZHttpEndpoints.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/ZHttpEndpoints.scala index d298c71241..0cec3ca389 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/ZHttpEndpoints.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/ZHttpEndpoints.scala @@ -1,6 +1,5 @@ package io.iohk.atala.agent.server.http -import io.iohk.atala.iam.authentication.oidc.JwtSecurityLogic import sttp.apispec.SecurityScheme import sttp.apispec.openapi.{OpenAPI, Server} import sttp.model.headers.AuthenticationScheme diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/sql/Migrations.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/sql/Migrations.scala index dc090b0667..d4cda1e7af 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/sql/Migrations.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/sql/Migrations.scala @@ -3,7 +3,9 @@ package io.iohk.atala.agent.server.sql import doobie.* import doobie.implicits.* import doobie.util.transactor.Transactor +import io.iohk.atala.shared.db.ContextAwareTask import io.iohk.atala.shared.db.DbConfig +import io.iohk.atala.shared.db.Implicits.* import org.flywaydb.core.Flyway import zio.* import zio.interop.catz.* @@ -35,6 +37,23 @@ object Migrations { val layer: URLayer[DbConfig, Migrations] = ZLayer.fromFunction(Migrations.apply _) + /** Fail if the RLS is not enabled from a sample table */ + def validateRLS: RIO[Transactor[ContextAwareTask], Unit] = { + val cxnIO = sql""" + | SELECT row_security_active('public.peer_did'); + """.stripMargin + .query[Boolean] + .unique + + for { + xa <- ZIO.service[Transactor[ContextAwareTask]] + isRlsActive <- cxnIO.transactWithoutContext(xa) + _ <- ZIO + .fail(Exception("The RLS policy is not active for Agent DB application user")) + .unless(isRlsActive) + } yield () + } + def initDbPrivileges(appUser: String): RIO[Transactor[Task], Unit] = { val cxnIO = for { _ <- doobie.free.connection.createStatement.map { stm =>