{"id":13541841,"url":"https://github.com/dschadow/CloudSecurity","last_synced_at":"2025-04-02T09:32:49.796Z","repository":{"id":27812044,"uuid":"87945120","full_name":"dschadow/CloudSecurity","owner":"dschadow","description":"Cloud security projects with Spring Cloud Config Server and Vault","archived":false,"fork":false,"pushed_at":"2024-10-23T06:38:08.000Z","size":1173,"stargazers_count":27,"open_issues_count":0,"forks_count":9,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-10-24T22:58:47.993Z","etag":null,"topics":["cipher","cloud-security","jasypt","java","spring","spring-boot","spring-cloud","spring-cloud-config","vault"],"latest_commit_sha":null,"homepage":"https://blog.dominikschadow.de","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dschadow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-11T14:38:14.000Z","updated_at":"2024-10-23T06:38:04.000Z","dependencies_parsed_at":"2023-11-08T23:21:49.508Z","dependency_job_id":"f84ce5e7-5ca0-43d6-9cee-aa83d4c43ce9","html_url":"https://github.com/dschadow/CloudSecurity","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dschadow%2FCloudSecurity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dschadow%2FCloudSecurity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dschadow%2FCloudSecurity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dschadow%2FCloudSecurity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dschadow","download_url":"https://codeload.github.com/dschadow/CloudSecurity/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246788855,"owners_count":20834177,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cipher","cloud-security","jasypt","java","spring","spring-boot","spring-cloud","spring-cloud-config","vault"],"created_at":"2024-08-01T10:00:57.685Z","updated_at":"2025-04-02T09:32:49.790Z","avatar_url":"https://github.com/dschadow.png","language":"Java","readme":"# Cloud Security Project Guidelines\n\n![Build](https://github.com/dschadow/CloudSecurity/workflows/Build/badge.svg) [![codecov](https://codecov.io/gh/dschadow/CloudSecurity/branch/main/graph/badge.svg?token=5gnWr92QHj)](https://codecov.io/gh/dschadow/CloudSecurity) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n\n## Project Overview\nThis project demonstrates cloud security implementations using Spring Cloud Config and HashiCorp Vault, with examples of secure configuration management and secret handling.\n\n## Tech Stack\n- Java 21\n- Spring Boot 3.4\n- Spring Cloud 2024\n- HashiCorp Vault 1.18\n- PostgreSQL 17\n- Jasypt for encryption\n- SpringDoc OpenAPI\n- Docker for containerization\n- Maven for build management\n\n## Project Structure\n```\nCloudSecurity/\n├── config-client/        # Basic config client implementation\n├── config-client-vault/  # Vault-integrated config client\n├── config-server/        # Basic config server\n├── config-server-vault/  # Vault-integrated config server\n├── standalone-client/    # Independent client implementation\n├── config-repo/         # Configuration repository\n└── Docker/             # Container configurations\n```\n\n## Architecture Overview\nThe system is designed with multiple layers of configuration and security management:\n\n```\n+-------------------------------------------------------------------------+\n|                           Client Applications                            |\n|  +----------------+  +-------------------+  +------------------+         |\n|  | Standalone     |  | Config Client     |  | Config Client    |         |\n|  | Client         |  | (Basic)           |  | (Vault)          |         |\n|  | [Jasypt]       |  |                   |  |                  |         |\n|  +--------+-------+  +---------+---------+  +--------+---------+         |\n|           |                    |                     |                    |\n|           |                    |                     |                    |\n+-----------|--------------------+---------------------|--------------------+\n            |                    |                     |\n            v                    v                     v\n+-------------------------------------------------------------------------+\n|                        Configuration Layer                               |\n|  +----------------+  +-------------------+  +------------------+         |\n|  | Jasypt         |  | Config Server     |  | Config Server    |         |\n|  | Encryption     |  | (Basic)           |  | (Vault)          |         |\n|  |                |  |                   |  |                  |         |\n|  +----------------+  +--------+----------+  +--------+---------+         |\n|                              |                       |                    |\n+------------------------------|-----------------------)--------------------+\n                              |                       |\n                              v                       v\n+-------------------------------------------------------------------------+\n|                        Security \u0026 Storage                                |\n|  +----------------+  +-------------------+  +------------------+         |\n|  | Config Repo    |  | HashiCorp         |  | PostgreSQL       |         |\n|  | (Git)          |  | Vault             |  | Database         |         |\n|  |                |  |                   |  |                  |         |\n|  +----------------+  +-------------------+  +------------------+         |\n|                                                                         |\n+-------------------------------------------------------------------------+\n```\n\nThe architecture consists of three main layers:\n\n1. **Client Applications Layer**\n   - Standalone Client with Jasypt encryption\n   - Basic Config Client using Spring Cloud Config\n   - Vault-enabled Config Client for advanced secret management\n\n2. **Configuration Layer**\n   - Basic Config Server for centralized configuration\n   - Vault-enabled Config Server for secure secret management\n   - Jasypt encryption for standalone operations\n\n3. **Security \u0026 Storage Layer**\n   - Git-based Configuration Repository\n   - HashiCorp Vault for secret management and dynamic credentials\n   - PostgreSQL database for application data\n\n### standalone-client\nThe standalone application is using [Jasypt for Spring Boot](https://github.com/ulisesbocchio/jasypt-spring-boot) to secure sensitive configuration properties. This demo application shows the simplest way to encrypt sensitive properties without requiring another service or system. You have to provide an environment variable named `jasypt.encryptor.password` with the value `sample-password` to decrypt the database password during application start. After launching, `http://localhost:8080` shows basic application information.\n\n### Spring Cloud Config\nAll client applications use [Spring Cloud Config](https://cloud.spring.io/spring-cloud-config/) to separate code and configuration and therefore require a running config server before starting the actual application.\n\n#### config-server\nThis project contains the Spring Cloud Config server which must be started like a Spring Boot application before using the **config-client** web application. After starting the config server with the default profile, the server is available on port 8888 and will use the configuration files provided in the **config-repo** folder in my GitHub repository. Starting the config server without a profile therefore requires Internet access to read the configuration files\n\nThere are two application configurations available:\n- **config-client** with the profile [cipher](http://localhost:8888/config-client/cipher)\n- **config-client** with the profile [plain](http://localhost:8888/config-client/plain)\n\n#### config-client\nThis Spring Boot based web application exposes the REST endpoints `/`, `/users` and `/credentials`. Depending on the active Spring profile, the configuration files used are not encrypted (**plain**) or secured using Spring Config encryption functionality (**cipher**). There is no default profile available, so you have to provide a specific profile during start.\n\n##### Profile plain\nConfiguration files are not protected at all, even sensitive configuration properties are stored in plain text.\n\n##### Profile cipher\nThis profile uses Config Server functionality to encrypt sensitive properties. It requires either a symmetric or asymmetric key. The sample is based on asymmetric encryption and is using a keystore (`server.jks`) which was created with the following command:\n\n    keytool -genkeypair -alias configserver -storetype JKS -keyalg RSA \\\n      -dname \"CN=Config Server,OU=Unit,O=Organization,L=City,S=State,C=Germany\" \\\n      -keypass secret -keystore server.jks -storepass secret\n\nThe Config Server endpoints help to encrypt and decrypt data:\n\n    curl http://localhost:8888/encrypt -d secretToEncrypt\n    curl http://localhost:8888/decrypt -d secretToDecrypt\n\n## Build \u0026 Run\n1. Build the project:\n   ```bash\n   mvn clean install\n   ```\n\n2. Start infrastructure:\n   ```bash\n   cd Docker\n   docker-compose up -d\n   ```\n\n3. Initialize Vault:\n   - Open Vault UI at http://localhost:8200\n   - Use the following unseal keys (any 3 out of 5):\n     ```\n     Key 1: ndPiS12Q92PqSdahBL4xFkDSjHTivINXQeC62jUv6tVa\n     Key 2: 8FpTPAQSFj2j2NyAt1V47iZtBn4g+a3V5hgc6L6ogiw5\n     Key 3: xRDWjq+0n72AjfC6Zt19Aiw3XCnMBJ424QoKATDROi+F\n     Key 4: wBEG41KMWWpYbhYwtSl/+0hYOhSNQGhsvH8T1FZiJh4w\n     Key 5: YJ+WiIAzWDatj3eAiiULjw/BoNF+30DWsrFqs6xnDadR\n     ```\n   - Initial Root Token: `hvs.WzBcwSIguPzLnhfJmPaCIMnK`\n\n4. Run applications in order:\n   - Start config-server or config-server-vault\n   - Start client applications\n\n## Testing\n- JUnit tests are available for each module\n- Run tests with: `mvn test`\n- JaCoCo test coverage reports are generated automatically\n- Test reports location: `target/site/jacoco/index.html`\n\n## Manual Vault Configuration\nIn case you don't want to use the configured Vault Docker container you can find all required commands to initialize Vault below:\n\n    vault server -config Docker/config/file-storage.hcl\n    export VAULT_ADDR=http://127.0.0.1:8200\n    vault operator init\n    export VAULT_TOKEN=[Root Token]\n    vault operator unseal [Key 1]\n    vault operator unseal [Key 2]\n    vault operator unseal [Key 3]\n\nExecute the following commands in order to enable the required backend and other services and to provide the required data:\n\n    # enable secrets backend\n    vault secrets enable -path=secret kv-v2\n\n    # provide configuration data for the config-client-vault application\n    vault kv put secret/Config-Client-Vault config.client.vault.application.name=\"Config Client Vault\" config.client.vault.application.profile=\"vault\"\n\n    # import policy\n    vault policy write config-client-policy Docker/policies/config-client-policy.hcl\n\n    # create a token for config-client-vault\n    vault token create -policy=config-client-policy\n\n    # enable and configure AppRole authentication\n    vault auth enable approle\n\n    # create roles with 24 hour TTL (can be renewed for up to 48 hours of its first creation)\n    vault write auth/approle/role/config-client \\\n        token_ttl=24h \\\n        token_max_ttl=48h \\\n        token_policies=config-client-policy\n\n    # update config-client-vault/application.yml with the returned role-id\n    vault read auth/approle/role/config-client/role-id\n\n    # update config-client-vault/application.yml with the returned secret-id\n    vault write -f auth/approle/role/config-client/secret-id\n\n    # enable the Transit backend and provide a key\n    vault secrets enable transit\n    vault write -f transit/keys/symmetric-sample-key\n\n    # enable dynamic database secrets\n    vault secrets enable database\n\n    # create an all privileges role\n    vault write database/roles/config_client_vault_all_privileges \\\n          db_name=config_client_vault \\\n          creation_statements=\"CREATE ROLE \\\"{{name}}\\\" \\\n            WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \\\n            GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \\\"{{name}}\\\"; \\\n            ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO \\\"{{name}}\\\";\" \\\n          revocation_statements=\"ALTER ROLE \\\"{{name}}\\\" NOLOGIN;\" \\\n          default_ttl=\"24h\" \\\n          max_ttl=\"48h\"\n\n    # create the database connection (the database must already exist, create it with \"CREATE DATABASE config_client_vault;\")\n    vault write database/config/config_client_vault \\\n        plugin_name=postgresql-database-plugin \\\n        allowed_roles=\"*\" \\\n        connection_url=\"postgresql://{{username}}:{{password}}@postgres:5432/config_client_vault?sslmode=disable\" \\\n        username=\"postgres\" \\\n        password=\"password\"\n\n    # force rotation for root user (THIS WILL DESTROY the existing root password, make sure you have another one)\n    vault write --force /database/rotate-root/config_client_vault\n\n    # create new credentials\n    vault read database/creds/config_client_vault_all_privileges\n","funding_links":[],"categories":["Projects"],"sub_categories":["Spring"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdschadow%2FCloudSecurity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdschadow%2FCloudSecurity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdschadow%2FCloudSecurity/lists"}