diff --git a/tests/integration-tests/build.gradle.kts b/tests/integration-tests/build.gradle.kts index ea7b9a924f..221265ae72 100644 --- a/tests/integration-tests/build.gradle.kts +++ b/tests/integration-tests/build.gradle.kts @@ -44,6 +44,8 @@ dependencies { // Hoplite for configuration implementation("com.sksamuel.hoplite:hoplite-core:2.7.5") implementation("com.sksamuel.hoplite:hoplite-hocon:2.7.5") + // Kotlin compose + testImplementation("org.testcontainers:testcontainers:1.19.1") } buildscript { diff --git a/tests/integration-tests/src/test/kotlin/config/AgentConf.kt b/tests/integration-tests/src/test/kotlin/config/AgentConf.kt index 3918ef0960..38d5e87649 100644 --- a/tests/integration-tests/src/test/kotlin/config/AgentConf.kt +++ b/tests/integration-tests/src/test/kotlin/config/AgentConf.kt @@ -5,7 +5,7 @@ import java.net.URL data class AgentConf( val url: URL, + val apikey: String?, @ConfigAlias("webhook_url") val webhookUrl: URL?, - var apikey: String?, - @ConfigAlias("multi-tenant") val multiTenant: Boolean?, + val init: AgentInitConf?, ) diff --git a/tests/integration-tests/src/test/kotlin/config/AgentInitConf.kt b/tests/integration-tests/src/test/kotlin/config/AgentInitConf.kt new file mode 100644 index 0000000000..3ba21e3cbe --- /dev/null +++ b/tests/integration-tests/src/test/kotlin/config/AgentInitConf.kt @@ -0,0 +1,12 @@ +package config + +import com.sksamuel.hoplite.ConfigAlias + +data class AgentInitConf( + val version: String, + @ConfigAlias("http_port") val httpPort: Int, + @ConfigAlias("didcomm_port") val didcommPort: Int, + @ConfigAlias("secret_storage_backend") val secretStorageBackend: String, + @ConfigAlias("auth_enabled") val authEnabled: Boolean, + @ConfigAlias("keycloak_enabled") val keycloakEnabled: Boolean, +) diff --git a/tests/integration-tests/src/test/kotlin/config/Config.kt b/tests/integration-tests/src/test/kotlin/config/Config.kt index c4abe8b62d..b5f7cd8130 100644 --- a/tests/integration-tests/src/test/kotlin/config/Config.kt +++ b/tests/integration-tests/src/test/kotlin/config/Config.kt @@ -2,8 +2,10 @@ package config data class Config( val global: GlobalConf, + val admin: AgentConf, val issuer: AgentConf, val holder: AgentConf, val verifier: AgentConf, - val admin: AgentConf + val agents: List, + val services: ServicesConf ) diff --git a/tests/integration-tests/src/test/kotlin/config/GlobalConf.kt b/tests/integration-tests/src/test/kotlin/config/GlobalConf.kt index e3e6d89a34..ade1a77c88 100644 --- a/tests/integration-tests/src/test/kotlin/config/GlobalConf.kt +++ b/tests/integration-tests/src/test/kotlin/config/GlobalConf.kt @@ -3,8 +3,6 @@ package config import com.sksamuel.hoplite.ConfigAlias data class GlobalConf( - @ConfigAlias("auth_required") val authRequired: Boolean, - @ConfigAlias("auth_header") val authHeader: String, - @ConfigAlias("admin_auth_header") val adminAuthHeader: String, - @ConfigAlias("admin_apikey") val adminApiKey: String + @ConfigAlias("auth_header") val authHeader: String = "apikey", + @ConfigAlias("admin_auth_header") val adminAuthHeader: String = "x-admin-api-key", ) diff --git a/tests/integration-tests/src/test/kotlin/config/ServicesConf.kt b/tests/integration-tests/src/test/kotlin/config/ServicesConf.kt new file mode 100644 index 0000000000..691afbc4e1 --- /dev/null +++ b/tests/integration-tests/src/test/kotlin/config/ServicesConf.kt @@ -0,0 +1,31 @@ +package config + +import com.sksamuel.hoplite.ConfigAlias + +data class ServicesConf( + @ConfigAlias("prism_node") val prismNode: PrismNodeConf?, + val keycloak: KeycloakConf?, + val vault: VaultConf?, +) + +data class PrismNodeConf( + @ConfigAlias("http_port") val httpPort: Int, + val version: String, +) + +data class KeycloakConf( + @ConfigAlias("http_port") val httpPort: Int, + val realm: String, + @ConfigAlias("client_id") val clientId: String, + @ConfigAlias("client_secret") val clientSecret: String, + val users: List +) + +data class KeycloakUser( + val username: String, + val password: String +) + +data class VaultConf( + @ConfigAlias("http_port") val httpPort: Int, +) diff --git a/tests/integration-tests/src/test/kotlin/features/CommonSteps.kt b/tests/integration-tests/src/test/kotlin/features/CommonSteps.kt index 95a9ab8762..9b57398b34 100644 --- a/tests/integration-tests/src/test/kotlin/features/CommonSteps.kt +++ b/tests/integration-tests/src/test/kotlin/features/CommonSteps.kt @@ -2,12 +2,10 @@ package features import com.sksamuel.hoplite.ConfigLoader import common.ListenToEvents -import config.AgentConf -import config.Config +import config.* import features.connection.ConnectionSteps import features.credentials.IssueCredentialsSteps import features.did.PublishDidSteps -import features.multitenancy.EventsSteps import interactions.Get import io.cucumber.java.AfterAll import io.cucumber.java.BeforeAll @@ -24,50 +22,142 @@ import net.serenitybdd.screenplay.actors.OnStage import net.serenitybdd.screenplay.rest.abilities.CallAnApi import org.apache.http.HttpStatus import org.apache.http.HttpStatus.SC_OK -import java.util.* -import kotlin.random.Random +import org.testcontainers.containers.ComposeContainer +import org.testcontainers.containers.wait.strategy.Wait +import java.io.File -@OptIn(ExperimentalStdlibApi::class) -fun createWalletAndEntity(agentConf: AgentConf) { - val config = ConfigLoader().loadConfigOrThrow("/tests.conf") - val createWalletResponse = RestAssured - .given().body( - CreateWalletRequest( - name = UUID.randomUUID().toString(), - seed = Random.nextBytes(64).toHexString(), - id = UUID.randomUUID() - ) +val environments: MutableList = mutableListOf() + +fun initializeVdr(prismNode: PrismNodeConf) { + val vdrEnvironment: ComposeContainer = ComposeContainer( + File("src/test/resources/containers/vdr.yml") + ).withEnv( + mapOf( + "PRISM_NODE_VERSION" to prismNode.version, + "PRISM_NODE_PORT" to prismNode.httpPort.toString() ) - .header(config.global.adminAuthHeader, config.global.adminApiKey) - .post("${agentConf.url}/wallets") - .thenReturn() - Ensure.that(createWalletResponse.statusCode).isEqualTo(HttpStatus.SC_CREATED) - val wallet = createWalletResponse.body.jsonPath().getObject("", WalletDetail::class.java) - val tenantResponse = RestAssured - .given().body( - CreateEntityRequest( - name = UUID.randomUUID().toString(), - walletId = wallet.id - ) + ).waitingFor( + "prism-node", Wait.forLogMessage(".*Server started, listening on.*", 1) + ) + environments.add(vdrEnvironment) + vdrEnvironment.start() +} + +fun initializeKeycloak(keycloakConf: KeycloakConf) { + val keycloakEnvironment: ComposeContainer = ComposeContainer( + File("src/test/resources/containers/keycloak.yml") + ).withEnv( + mapOf( + "KEYCLOAK_HTTP_PORT" to keycloakConf.httpPort.toString(), ) - .header(config.global.adminAuthHeader, config.global.adminApiKey) - .post("${agentConf.url}/iam/entities") - .thenReturn() - Ensure.that(tenantResponse.statusCode).isEqualTo(HttpStatus.SC_CREATED) - val entity = tenantResponse.body.jsonPath().getObject("", EntityResponse::class.java) - val addApiKeyResponse = + ).waitingFor( + "keycloak", Wait.forLogMessage(".*Running the server.*", 1) + ) + environments.add(keycloakEnvironment) + keycloakEnvironment.start() + + // Get admin token + val getAdminTokenResponse = + RestAssured + .given().body("grant_type=password&client_id=admin-cli&username=admin&password=admin") + .contentType("application/x-www-form-urlencoded") + .post("http://localhost:${keycloakConf.httpPort}/realms/master/protocol/openid-connect/token") + .thenReturn() + Ensure.that(getAdminTokenResponse.statusCode).isEqualTo(SC_OK) + val adminToken = getAdminTokenResponse.body.jsonPath().getString("access_token") + + // Create realm + val createRealmResponse = RestAssured .given().body( - ApiKeyAuthenticationRequest( - entityId = entity.id, - apiKey = agentConf.apikey!! + mapOf( + "realm" to keycloakConf.realm, + "enabled" to true ) ) - .header(config.global.adminAuthHeader, config.global.adminApiKey) - .post("${agentConf.url}/iam/apikey-authentication") + .header("Authorization", "Bearer $adminToken") + .contentType("application/json") + .post("http://localhost:${keycloakConf.httpPort}/admin/realms") .thenReturn() - Ensure.that(addApiKeyResponse.statusCode).isEqualTo(HttpStatus.SC_CREATED) - val registerIssuerWebhookResponse = + Ensure.that(createRealmResponse.statusCode).isEqualTo(SC_OK) + + // Create client + val createClientResponse = + RestAssured + .given().body( + mapOf( + "id" to keycloakConf.clientId, + "directAccessGrantsEnabled" to true, + "authorizationServicesEnabled" to true, + "serviceAccountsEnabled" to true, + "secret" to keycloakConf.clientSecret, + )) + .header("Authorization", "Bearer $adminToken") + .contentType("application/json") + .post("http://localhost:${keycloakConf.httpPort}/admin/realms/${keycloakConf.realm}/clients") + .thenReturn() + Ensure.that(createClientResponse.statusCode).isEqualTo(SC_OK) + + // Create users + keycloakConf.users.forEach { keycloakUser -> + val createUserResponse = + RestAssured + .given().body( + mapOf( + "id" to keycloakUser.username, + "username" to keycloakUser.username, + "firstName" to keycloakUser.username, + "enabled" to true, + "credentials" to listOf( + mapOf( + "value" to keycloakUser.password, + "temporary" to false + ) + ) + ) + ) + .header("Authorization", "Bearer $adminToken") + .contentType("application/json") + .post("http://localhost:${keycloakConf.httpPort}/admin/realms/${keycloakConf.realm}/users") + .thenReturn() + Ensure.that(createUserResponse.statusCode).isEqualTo(SC_OK) + } +} + +fun initializeAgent(agentInitConf: AgentInitConf) { + val config = ConfigLoader().loadConfigOrThrow("/tests.conf") + val agentConfMap: Map = mapOf( + "OPEN_ENTERPRISE_AGENT_VERSION" to agentInitConf.version, + "API_KEY_ENABLED" to agentInitConf.authEnabled.toString(), + "AUTH_HEADER" to config.global.authHeader, + "ADMIN_AUTH_HEADER" to config.global.adminAuthHeader, + "AGENT_DIDCOMM_PORT" to agentInitConf.didcommPort.toString(), + "AGENT_HTTP_PORT" to agentInitConf.httpPort.toString(), + "PRISM_NODE_PORT" to if (config.services.prismNode != null) + config.services.prismNode.httpPort.toString() else "", + "SECRET_STORAGE_BACKEND" to agentInitConf.secretStorageBackend, + "VAULT_HTTP_PORT" to if (config.services.vault != null && agentInitConf.secretStorageBackend == "vault") + config.services.vault.httpPort.toString() else "", + "KEYCLOAK_ENABLED" to agentInitConf.keycloakEnabled.toString(), + "KEYCLOAK_HTTP_PORT" to if (config.services.keycloak != null && agentInitConf.keycloakEnabled) + config.services.keycloak.httpPort.toString() else "", + "KEYCLOAK_REALM" to if (config.services.keycloak != null && agentInitConf.keycloakEnabled) + config.services.keycloak.realm else "", + "KEYCLOAK_CLIENT_ID" to if (config.services.keycloak != null && agentInitConf.keycloakEnabled) + config.services.keycloak.clientId else "", + "KEYCLOAK_CLIENT_SECRET" to if (config.services.keycloak != null && agentInitConf.keycloakEnabled) + config.services.keycloak.clientSecret else "", + ) + val environment: ComposeContainer = ComposeContainer( + File("src/test/resources/containers/agent.yml") + ).withEnv(agentConfMap).waitingFor("open-enterprise-agent", Wait.forHealthcheck()) + environments.add(environment) + environment.start() +} + +fun initializeWebhook(agentConf: AgentConf) { + val config = ConfigLoader().loadConfigOrThrow("/tests.conf") + val registerWebhookResponse = RestAssured .given().body( CreateWebhookNotification( @@ -77,17 +167,24 @@ fun createWalletAndEntity(agentConf: AgentConf) { .header(config.global.authHeader, agentConf.apikey) .post("${agentConf.url}/events/webhooks") .thenReturn() - Ensure.that(registerIssuerWebhookResponse.statusCode).isEqualTo(HttpStatus.SC_CREATED) + Ensure.that(registerWebhookResponse.statusCode).isEqualTo(HttpStatus.SC_CREATED) +} + +fun getKeycloakAuthToken(keycloakConf: KeycloakConf, username: String, password: String): String { + val tokenResponse = + RestAssured + .given().body("grant_type=password&client_id=${keycloakConf.clientId}&client_secret=${keycloakConf.clientSecret}&username=${username}&password=${password}") + .contentType("application/x-www-form-urlencoded") + .post("http://localhost:${keycloakConf.httpPort}/realms/${keycloakConf.realm}/protocol/openid-connect/token") + .thenReturn() + Ensure.that(tokenResponse.statusCode).isEqualTo(SC_OK) + return tokenResponse.body.jsonPath().getString("access_token") } @BeforeAll fun initAgents() { val cast = Cast() val config = ConfigLoader().loadConfigOrThrow("/tests.conf") - cast.actorNamed( - "Admin", - CallAnApi.at(config.admin.url.toExternalForm()) - ) cast.actorNamed( "Acme", CallAnApi.at(config.issuer.url.toExternalForm()), @@ -105,15 +202,36 @@ fun initAgents() { ) OnStage.setTheStage(cast) - // Create issuer wallet and tenant - if (config.issuer.multiTenant!!) { - createWalletAndEntity(config.issuer) + + if (config.services.keycloak != null) { + initializeKeycloak(config.services.keycloak) + cast.actors.forEach { actor -> + when (actor.name) { + "Acme" -> { + actor.remember("KEYCLOAK_BEARER_TOKEN", getKeycloakAuthToken(config.services.keycloak, "Acme", "Acme")) + } + "Bob" -> { + actor.remember("KEYCLOAK_BEARER_TOKEN", getKeycloakAuthToken(config.services.keycloak, "Bob", "Bob")) + } + "Faber" -> { + actor.remember("KEYCLOAK_BEARER_TOKEN", getKeycloakAuthToken(config.services.keycloak, "Faber", "Faber")) + } + } + } } - // Create verifier wallet - if (config.verifier.multiTenant!!) { - createWalletAndEntity(config.verifier) + + if (config.services.prismNode != null) { + initializeVdr(config.services.prismNode) + } + // Initialize the agents + config.agents.forEach { agent -> + initializeAgent(agent) } + initializeWebhook(config.issuer) + initializeWebhook(config.holder) + initializeWebhook(config.verifier) + cast.actors.forEach { actor -> when (actor.name) { "Acme" -> { @@ -132,6 +250,9 @@ fun initAgents() { @AfterAll fun clearStage() { OnStage.drawTheCurtain() + environments.forEach { environment -> + environment.stop() + } } class CommonSteps { diff --git a/tests/integration-tests/src/test/kotlin/interactions/AuthRestInteraction.kt b/tests/integration-tests/src/test/kotlin/interactions/AuthRestInteraction.kt index 881c193dae..ac5f0b0364 100644 --- a/tests/integration-tests/src/test/kotlin/interactions/AuthRestInteraction.kt +++ b/tests/integration-tests/src/test/kotlin/interactions/AuthRestInteraction.kt @@ -2,7 +2,6 @@ package interactions import com.sksamuel.hoplite.ConfigLoader import config.Config -import io.ktor.util.* import io.restassured.specification.RequestSpecification import net.serenitybdd.screenplay.Actor import net.serenitybdd.screenplay.rest.interactions.RestInteraction @@ -13,12 +12,11 @@ abstract class AuthRestInteraction : RestInteraction() { fun specWithAuthHeaders(actor: T): RequestSpecification { val spec = rest() - if (actor!!.name.toLowerCasePreservingASCIIRules().contains("admin")) { - spec.header(config.global.adminAuthHeader, config.global.adminApiKey) - } else { - if (config.global.authRequired) { - spec.header(config.global.authHeader, actor.recall("AUTH_KEY")) - } + if (config.services.keycloak != null) { + spec.header("Authorization", "Bearer ${actor!!.recall("KEYCLOAK_BEARER_TOKEN")}") + } + if (actor!!.recall("AUTH_KEY") != null) { + spec.header(config.global.authHeader, actor.recall("AUTH_KEY")) } return spec } diff --git a/tests/integration-tests/src/test/resources/containers/agent.yml b/tests/integration-tests/src/test/resources/containers/agent.yml new file mode 100644 index 0000000000..c82e740a54 --- /dev/null +++ b/tests/integration-tests/src/test/resources/containers/agent.yml @@ -0,0 +1,66 @@ +--- +version: "3.8" + +services: + + # Mandatory PostgreSQL database for the Open Enterprise Agent + postgres: + image: postgres:13 + environment: + POSTGRES_MULTIPLE_DATABASES: "castor,pollux,connect,agent" + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + volumes: + - ./postgres/init-script.sh:/docker-entrypoint-initdb.d/init-script.sh + - ./postgres/max_conns.sql:/docker-entrypoint-initdb.d/max_conns.sql + healthcheck: + test: ["CMD", "pg_isready", "-U", "postgres", "-d", "agent"] + interval: 10s + timeout: 5s + retries: 5 + + # Secret storage - hashicorp + + # Open Enterprise Agent + open-enterprise-agent: + image: ghcr.io/input-output-hk/prism-agent:${OPEN_ENTERPRISE_AGENT_VERSION} + environment: + PRISM_NODE_HOST: host.docker.internal + PRISM_NODE_PORT: + CASTOR_DB_HOST: postgres + POLLUX_DB_HOST: postgres + CONNECT_DB_HOST: postgres + AGENT_DB_HOST: postgres + VAULT_TOKEN: root + # Configuration parameters + AGENT_DIDCOMM_PORT: + AGENT_HTTP_PORT: + DIDCOMM_SERVICE_URL: "http://host.docker.internal:${AGENT_DIDCOMM_PORT}" + REST_SERVICE_URL: "http://host.docker.internal:${AGENT_HTTP_PORT}" + AUTH_HEADER: + ADMIN_AUTH_HEADER: + API_KEY_ENABLED: + # Secret storage configuration + SECRET_STORAGE_BACKEND: + VAULT_ADDR: "http://host.docker.internal:${VAULT_HTTP_PORT}" + # Keycloak configuration + KEYCLOAK_ENABLED: + KEYCLOAK_URL: "http://host.docker.internal:${KEYCLOAK_HTTP_PORT}" + KEYCLOAK_REALM: + KEYCLOAK_CLIENT_ID: + KEYCLOAK_CLIENT_SECRET: + KEYCLOAK_UMA_AUTO_UPGRADE_RPT: true # no configurable at the moment + depends_on: + postgres: + condition: service_healthy + ports: + - "${AGENT_DIDCOMM_PORT}:${AGENT_DIDCOMM_PORT}" + - "${AGENT_HTTP_PORT}:${AGENT_HTTP_PORT}" + healthcheck: + test: ["CMD", "curl", "-f", "http://open-enterprise-agent:${AGENT_HTTP_PORT}/_system/health"] + interval: 10s + timeout: 5s + retries: 5 + # Extra hosts for Linux networking + extra_hosts: + - "host.docker.internal:host-gateway" diff --git a/tests/integration-tests/src/test/resources/containers/keycloak.yml b/tests/integration-tests/src/test/resources/containers/keycloak.yml new file mode 100644 index 0000000000..e9087992c9 --- /dev/null +++ b/tests/integration-tests/src/test/resources/containers/keycloak.yml @@ -0,0 +1,13 @@ +--- +version: "3.8" + +services: + + keycloak: + image: quay.io/keycloak/keycloak:22.0.4 + ports: + - "${KEYCLOAK_HTTP_PORT}:8080" + environment: + KEYCLOAK_ADMIN: admin + KEYCLOAK_ADMIN_PASSWORD: admin + command: start-dev --health-enabled=true diff --git a/tests/integration-tests/src/test/resources/containers/postgres/init-script.sh b/tests/integration-tests/src/test/resources/containers/postgres/init-script.sh new file mode 100755 index 0000000000..408264cf1e --- /dev/null +++ b/tests/integration-tests/src/test/resources/containers/postgres/init-script.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -e +set -u + +function create_user_and_database() { + local database=$1 + local app_user=${database}-application-user + echo " Creating user and database '$database'" + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL + CREATE USER "$app_user" WITH PASSWORD 'password'; + CREATE DATABASE $database; + \c $database + ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO "$app_user"; + EOSQL +} + +if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then + echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" + for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do + create_user_and_database $db + done + echo "Multiple databases created" +fi diff --git a/tests/integration-tests/src/test/resources/containers/postgres/max_conns.sql b/tests/integration-tests/src/test/resources/containers/postgres/max_conns.sql new file mode 100644 index 0000000000..f2a343e505 --- /dev/null +++ b/tests/integration-tests/src/test/resources/containers/postgres/max_conns.sql @@ -0,0 +1 @@ +ALTER SYSTEM SET max_connections = 500; diff --git a/tests/integration-tests/src/test/resources/containers/vault.yml b/tests/integration-tests/src/test/resources/containers/vault.yml new file mode 100644 index 0000000000..a54d316b09 --- /dev/null +++ b/tests/integration-tests/src/test/resources/containers/vault.yml @@ -0,0 +1,20 @@ +--- +version: "3.8" + +services: + + vault-server: + image: hashicorp/vault:1.13.3 + ports: + - "${VAULT_PORT}:8200" + environment: + VAULT_ADDR: "http://0.0.0.0:8200" + VAULT_DEV_ROOT_TOKEN_ID: root + command: server -dev -dev-root-token-id=root + cap_add: + - IPC_LOCK + healthcheck: + test: [ "CMD", "vault", "status" ] + interval: 10s + timeout: 5s + retries: 5 diff --git a/tests/integration-tests/src/test/resources/containers/vdr.yml b/tests/integration-tests/src/test/resources/containers/vdr.yml new file mode 100644 index 0000000000..b65b06e8bf --- /dev/null +++ b/tests/integration-tests/src/test/resources/containers/vdr.yml @@ -0,0 +1,28 @@ +--- +version: "3.8" + +services: + + node-db: + image: postgres:13 + environment: + POSTGRES_DB: "node_db" + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + healthcheck: + test: [ "CMD", "pg_isready", "-U", "postgres", "-d", "node_db" ] + interval: 10s + timeout: 5s + retries: 5 + + prism-node: + image: ghcr.io/input-output-hk/prism-node:${PRISM_NODE_VERSION} + environment: + NODE_PSQL_HOST: node-db:5432 + NODE_REFRESH_AND_SUBMIT_PERIOD: 1s + NODE_MOVE_SCHEDULED_TO_PENDING_PERIOD: 1s + ports: + - "${PRISM_NODE_PORT}:50053" + depends_on: + node-db: + condition: service_healthy diff --git a/tests/integration-tests/src/test/resources/tests.conf b/tests/integration-tests/src/test/resources/tests.conf index bd1065b8e6..97d4917083 100644 --- a/tests/integration-tests/src/test/resources/tests.conf +++ b/tests/integration-tests/src/test/resources/tests.conf @@ -1,32 +1,70 @@ +# Specify shared services that are used by all agents (if any) +services = { + prism_node = { + http_port = 50053 + version = "2.2.1" + } + keycloak = { + http_port = 9980 + realm = "atala-demo" + client_id = "prism-agent" + client_secret = "prism-agent-demo-secret" + users = [ + { + username = "Acme" + password = "Acme" + }, + { + username = "Bob" + password = "Bob" + }, + { + username = "Faber" + password = "Faber" + } + ] + } + vault = { + http_port = 8200 + } +} + +# Specify agents that are required to be created before running tests +agents = [ + { + version = "1.18.0" + http_port = 8080 + didcomm_port = 7080 + secret_storage_backend = "postgres" # can be vault + auth_enabled = true + keycloak_enabled = true + } +] + global { - auth_required = true auth_header = "${AUTH_HEADER:-apikey}" admin_auth_header = "${ADMIN_AUTH_HEADER:-x-admin-api-key}" - admin_apikey = "${ADMIN_API_KEY:-admin}" } admin { - url = "${ADMIN_AGENT_URL:-http://localhost:8080/prism-agent}" - apikey = "${ISSUER_API_KEY:-${random.string(16)}}" + url = "${ADMIN_AGENT_URL:-http://localhost:8080}" + apikey = "${ADMIN_API_KEY:-${random.string(16)}}" } issuer { - url = "${ISSUER_AGENT_URL:-http://localhost:8080/prism-agent}" - webhook_url = "${ISSUER_WEBHOOK_URL:-http://host.docker.internal:9955}" + url = "${ISSUER_AGENT_URL:-http://localhost:8080}" apikey = "${ISSUER_API_KEY:-${random.string(16)}}" - multi-tenant = true -} - -verifier { - url = "${VERIFIER_AGENT_URL:-http://localhost:8080/prism-agent}" - webhook_url = "${VERIFIER_WEBHOOK_URL:-http://host.docker.internal:9957}" - apikey = "${VERIFIER_API_KEY:-${random.string(16)}}" - multi-tenant = true + webhook_url = "${ISSUER_WEBHOOK_URL:-http://host.docker.internal:9955}" } holder { - url = "${HOLDER_AGENT_URL:-http://localhost:8090/prism-agent}" + url = "${HOLDER_AGENT_URL:-http://localhost:8080}" + apikey = "${HOLDER_API_KEY:-${random.string(16)}}" webhook_url = "${HOLDER_WEBHOOK_URL:-http://host.docker.internal:9956}" - apikey = "${HOLDER_API_KEY:-default}" - multi-tenant = false +} + +verifier { + url = "${VERIFIER_AGENT_URL:-http://localhost:8080}" + apikey = "${VERIFIER_API_KEY:-${random.string(16)}}" + webhook_url = "${VERIFIER_WEBHOOK_URL:-http://host.docker.internal:9957}" }