{"id":23033957,"url":"https://github.com/freenowtech/sauron","last_synced_at":"2025-08-14T15:33:47.271Z","repository":{"id":36952390,"uuid":"350404664","full_name":"freenowtech/sauron","owner":"freenowtech","description":"Sauron, the all seeing eye! It is a service to generate automated reports and track migrations, changes and dependency versions for backend services also report on known CVE and security issues.","archived":false,"fork":false,"pushed_at":"2024-08-15T11:41:32.000Z","size":3411,"stargazers_count":23,"open_issues_count":15,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-08-16T12:15:25.780Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/freenowtech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-22T16:00:24.000Z","updated_at":"2024-08-16T12:15:25.781Z","dependencies_parsed_at":"2023-11-08T23:36:22.199Z","dependency_job_id":"efb9203a-30fd-4d10-a739-cd22ee82cd4e","html_url":"https://github.com/freenowtech/sauron","commit_stats":null,"previous_names":[],"tags_count":164,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freenowtech%2Fsauron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freenowtech%2Fsauron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freenowtech%2Fsauron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freenowtech%2Fsauron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/freenowtech","download_url":"https://codeload.github.com/freenowtech/sauron/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229843383,"owners_count":18132900,"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":[],"created_at":"2024-12-15T16:28:16.153Z","updated_at":"2025-08-14T15:33:47.264Z","avatar_url":"https://github.com/freenowtech.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SAURON - VERSION AND DEPLOYMENT TRACKER\n\n[![Release](https://img.shields.io/github/v/release/freenowtech/sauron)](https://github.com/freenowtech/sauron/releases/latest)\n[![Downloads](https://img.shields.io/github/downloads/freenowtech/sauron/total?label=release%20binary%20downloads)](https://github.com/freenowtech/sauron/releases/latest)\n[![Build](https://github.com/freenowtech/sauron/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/freenowtech/sauron/actions/workflows/build.yml)\n[![Release Components](https://github.com/freenowtech/sauron/actions/workflows/release-components.yml/badge.svg)](https://github.com/freenowtech/sauron/actions/workflows/release-components.yml)\n[![Release Plugins](https://github.com/freenowtech/sauron/actions/workflows/release-plugins.yml/badge.svg)](https://github.com/freenowtech/sauron/actions/workflows/release-plugins.yml)\n\n\u003cp align=\"center\" style=\"background-color:black;\"\u003e\n  \u003cimg src=\"https://steamuserimages-a.akamaihd.net/ugc/541883619699450274/D25F66426956C58E110013352AE49102BD01BCE2/\" /\u003e\n\u003c/p\u003e\n\n## DESCRIPTION\n\nSauron, the all seeing eye! It is a service to generate automated reports and track migrations, changes and dependency\nversions for backend services also report on known CVE and security issues. A detailed description can be\nfound in the internal RFC document.\n\n---\n\n## COMPONENTS\n\nSauron Service is segregated into a few components that are described below:\n\n- **Sauron Core:** Sauron common library to be used by all sauron plugins. More details\n[here](https://github.com/freenowtech/sauron/tree/main/sauron-core)\n\n- **Sauron Service:** Sauron entrypoint controller described in more details in this README\n\n- **Sauron Plugin System:** Sauron has an embedded plugin support that allows anyone to introduce its own logic without\nthe need to rebuild, regenerate and stop/restart Sauron Service. More details in further sections.\n\n- **Elasticsearch Cluster:** Sauron uses [Elasticsearch](https://www.elastic.co) as a data storage. It is currently\ndeployed in AWS and can be accessed\n[here](http://localhost:9200).\n\n- **Kibana:** Elasticsearch data can be explored using the built-in [Kibana](https://www.elastic.co/products/kibana)\ninstance that can be accessed [here](http://localhost:5601).\n\n- **Dependencytrack:** Sauron includes an instance of [Dependencytrack](https://dependencytrack.org), a platform that\n allows organizations to identify and reduce risk from the use of third-party and open source components.\n\n---\n\n## ARCHITECTURE OVERVIEW\n\n![Sauron Service Architecture](https://github.com/freenowtech/sauron/blob/main/sauron-service/docs/sauron-service.png)\n\n---\n\n## RUNNING\n\nSauron can be deployed using [Docker](https://www.docker.com/) and [Docker-Compose](https://docs.docker.com/compose/).\nIt provides a Dockerfile that can be built using the following commands:\n\nBuild Sauron project using maven and ship it to a docker image:\n\n```commandline\nmake\n```\n\nStart Sauron stack and load the [local plugin repository](https://github.com/freenowtech/sauron/blob/main/sauron-service/plugins/plugins.json)\n\n```commandline\ndocker-compose -f docker-compose.yml --compatibility up\n```\n\nThis command will start three components:\n\n- elasticsearch: http://localhost:9200\n- kibana: http://localhost:5601\n- sauron-service: http://localhost:8080\n\n**Note**: *Since Sauron needs your maven, gradle, pip and nodejs configuration, the `docker-compose.yml` creates a volume\nfor each configuration folder/file. If there is no configuration already created, please create one before running\nthe command above. For more details please refer to\n[docker-compose.yaml \u003e Volumes](https://github.com/freenowtech/sauron/blob/main/sauron-service/docker-compose.yml#L48)*\n\n### Docker\n\nIn order to run Sauron with you predefined configuration using docker, use the command below:\n\n```shell\ndocker run \\\n    -e SPRING_CONFIG_LOCATION=\"/sauron/config/sauron-service.yml\" \\\n    -e M2_HOME=\"/usr/share/maven\" \\\n    -e SPRING_PROFILES_INCLUDE=\"local\" \\\n    -e SPRING_CLOUD_CONFIG_ENABLED=\"false\" \\\n    --mount type=bind,source=${PWD}/sauron-service/docker/config/sauron-service.yml,destination=/sauron/config/sauron-service.yml,readonly \\\n    --mount type=bind,source=${PWD}/sauron-service/plugins,destination=/sauron/plugins \\\n    --mount type=bind,source=${HOME}/.m2,destination=/root/.m2 \\\n    --mount type=bind,source=${HOME}/.gradle,destination=/root/.gradle \\\n    --mount type=bind,source=${HOME}/.pip,destination=/root/.pip \\\n    --mount type=bind,source=${HOME}/.npmrc,destination=/root/.npmrc \\\n    --mount type=bind,source=${HOME}/.ssh,destination=/root/.ssh,readonly \\\n    --name=sauron \\\n    -p 8080:8080 \\\n    ghcr.io/freenowtech/sauron/sauron-service:latest\n```\n\nIf you need to use a specific version, please refer to [Sauron Packages](https://github.com/orgs/freenowtech/packages/container/package/sauron%2Fsauron-service)\n\n---\n\n## CONFIGURATION\n\nSauron configuration can be set via `application.properties` file. The file path can be provided using the environment\nvariable:\n\n- **SPRING_CONFIG_LOCATION:** it must contain the path pointing to the local file\ne.g. `/path/to/config/my-properties.properties` or `/path/to/config/my-properties.yaml`\n\nSauron supports\n[Spring Cloud Config Server](https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_server.html)\nas a configuration provider. In order to set Config Server url, please use the environment variable below:\n\n- **SPRING_CLOUD_CONFIG_URI:** it must contain the URL pointing to the remote repository\ne.g. `https://my-repository.com/my-config`\n\nFor a Sauron configuration file example, please refer to\n[sauron-service.yml](https://github.com/freenowtech/sauron/blob/main/sauron-service/docker/config/sauron-service.yml)\n\n---\n\n## USAGE\n\n### Sauron Elasticsearch Index Template\n\nBefore start using Sauron, it is import to define the\n[index template](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/indices-templates.html) that will be used\nby Elasticsearch to create Sauron's index. It can be done by running the command line below:\n\n ```commandline\nelasticsearch/sauron-template.sh\nelasticsearch/dependencies-template.sh\n```\n\nThis template increases the number of fields, since usually the amount of dependencies and thus the amount of fields is\nhuge, and some other minor optimizations.\n\n### Triggering Sauron Service\n\nSauron Service provides a REST api that allows one to trigger a new build. The detailed parameters can be found in its\n[swagger documentation](http://localhost:8080/v2/api-docs). Once a new build has been triggered, Sauron's pipeline will\nrun applying all plugins pre-configured. The output will be stored in elasticsearch and can be queried afterwards using\nthe [Kibana Installation](http://localhost:5601).\n\nFor more details, check in the next section how the plugin system works.\n\nA build request example can be found below:\n\n```shell script\ncurl --verbose --location --request POST 'http://localhost:8080/api/v1/build' \\\n    --header 'Content-Type: application/json' \\\n    --data-raw '{\n      \"serviceName\": \"MyService\",\n      \"repositoryUrl\": \"https://github.com/gazgeek/springboot-helloworld.git\",\n      \"commitId\": \"41c7823dddbef43680a0726ccea0631519b9d3c1\",\n      \"buildId\": \"2b8caa6c-8b55-4b57-b654-5a00d519f409\",\n      \"owner\": \"Sauron\",\n      \"eventTime\": 1586962717770,\n      \"rollback\": false,\n      \"returnCode\": 0,\n      \"environment\": \"production\",\n      \"release\": \"0.0.1\",\n      \"user\": \"sauron-user\",\n      \"dockerImage\": \"helloworld:0.0.1\",\n      \"platform\": \"K8S\"\n    }'\n```\n\n### Visualizing Sauron Data\n\nAs mentioned before, Sauron stack uses Elasticsearch + Kibana to respectively store and visualize data. Once the\n Sauron build is done, the information will be available and can be queried using [Kibana](http://localhost:5601).\n\nIn order to do that, a index pattern must be created in Kibana using this\n[HOWTO](https://www.elastic.co/guide/en/kibana/6.8/tutorial-define-index.html).\n\nOnce it is done, you are able to use your data. Sauron provides a default Kibana Dashboard available\n[here](https://github.com/freenowtech/sauron/blob/main/sauron-service/kibana/kibana.ndjson).\n[Import](https://www.elastic.co/guide/en/kibana/current/dashboard-import-api.html) it and voilà! Enjoy your data!\n\n#### Kibana Dashboard Example\n\n![Sauron Kibana Dashboard](https://github.com/freenowtech/sauron/blob/main/sauron-service/docs/kibana.png)\n\n---\n\n## SAURON PLUGIN SYSTEM\n\nSauron has an embedded plugin system that allows anyone to insert its own business logic to extract\ninformation during the building/deploy process. It uses the [PF4J](https://github.com/pf4j/pf4j) which is a plugin\nframework written in Java, and provides a nice interface to implement an integration in your service.\n\nDuring the startup Sauron loads all available plugins, and updates them according to the scheduler configuration using the pre-defined\nplugin repository (Local or Artifactory). For more details please refer to\n[sauron-service.yml](https://github.com/freenowtech/sauron/blob/main/sauron-service/docker/config/sauron-service.yml).\n\n### Official Plugins\n\n#### [console Output](https://github.com/freenowtech/sauron/tree/main/plugins/console-output)\nPrints the DataSet content to `sysout`.\n\n#### [data-sanitizer](https://github.com/freenowtech/sauron/tree/main/plugins/data-sanitizer)\nSanitizes the data before being processed by Sauron pipeline.\n\n#### [git-checkout](https://github.com/freenowtech/sauron/tree/main/plugins/git-checkout)\nCheckout the project source code.\n\n#### [dependency-checker](https://github.com/freenowtech/sauron/tree/main/plugins/dependency-checker)\nExtracts dependencies information in [CycloneDX](https://cyclonedx.org/#specification-overview) and insert in DataSet.\n\n#### [dependencytrack-publisher](https://github.com/freenowtech/sauron/tree/main/plugins/dependencytrack-publisher)\nPublishes the dependencies to our internal [Dependency Track](https://dependencytrack.org) instance.\n\n#### [maven-report](https://github.com/freenowtech/sauron/tree/main/plugins/maven-report)\nRetrieves information from `pom.xml` file.\n\n#### [elasticsearch-output](https://github.com/freenowtech/sauron/tree/main/plugins/elasticsearch-output)\nStores the DataSet content into Elasticsearch.\n\n#### [protocw-checker](https://github.com/freenowtech/sauron/tree/main/plugins/protocw-checker)\nChecks whether a service is using `protoc`, and the [`protoc wrapper`](https://github.com/freenowtech/protoc-wrapper).\n\n#### [logs-report](https://github.com/freenowtech/sauron/tree/main/plugins/logs-report)\nTells if your service has any logs on elasticsearch. You can configure indexes and time range to search for logs.\n\n#### [kubernetesapi-report](https://github.com/freenowtech/sauron/tree/main/plugins/kubernetesapi-report)\nAllows Sauron to query Kubernetes API to retrieve the annotations and labels assigned to the resources, specified in the configuration, and stores the values into the DataSet.\n\n#### [sonarapi-report](https://github.com/freenowtech/sauron/tree/main/plugins/sonarapi-report)\nQuery [Sonar API](https://docs.sonarqube.org/latest/extend/web-api/) to retrieve your service related data, like Code Coverage, and stores into the DataSet.\n\n#### [thanosapi-report](https://github.com/freenowtech/sauron/tree/main/plugins/thanosapi-report)\nQuery [Thanos API](https://github.com/thanos-io/thanos/blob/main/docs/components/query.md) to retrieve your service related data(like RPM, Circuit Breaker), and stores into the DataSet.\n\n#### [readme-checker](https://github.com/freenowtech/sauron/tree/main/plugins/readme-checker)\nChecks whether a service has or not a README.md file in its root folder.\n\n#### [bcrypt-passwordencoder-checker](https://github.com/freenowtech/sauron/tree/main/plugins/bcrypt-passwordencoder-checker)\nChecks whether a service might be using `Bcrypt` to encode the passwords in the API\n\n#### [jaegerapi-report](https://github.com/freenowtech/sauron/tree/main/plugins/jaegerapi-report)\nQuery [Jaeger API](https://www.jaegertracing.io/docs/1.22/apis/) to extract tracing information\n\n#### [cleanup](https://github.com/freenowtech/sauron/tree/main/plugins/cleanup)\nCleanup Sauron workspace after each pipeline processing\n\n\n### Creating a New Sauron Plugin\n\nSauron provides a [maven archetype](https://maven.apache.org/guides/introduction/introduction-to-archetypes.html)\nin order to create a standard skeleton of a new plugin. To use that follow the steps below.\n\n#### Install maven archetype\n\nCheckout the [sauron-plugin-archetype](https://github.com/freenowtech/sauron/tree/main/sauron-plugin-archetype)\nproject:\n\n```bash\n$ git clone https://github.com/freenowtech/sauron.git\n```\n\nInstall the archetype locally and add it to the local archetype catalog:\n\n```bash\n$ cd sauron-plugin-archetype\n$ mvn clean install\n```\n\n#### Create new plugin skeleton\n\nGenerate the new plugin using the installed archetype:\n\n```bash\n$ mvn org.apache.maven.plugins:maven-archetype-plugin:3.1.2:generate\n[INFO] Scanning for projects...\n[INFO]\n[INFO] ------------------\u003c org.apache.maven:standalone-pom \u003e-------------------\n[INFO] Building Maven Stub Project (No POM) 1\n[INFO] --------------------------------[ pom ]---------------------------------\n[INFO]\n[INFO] \u003e\u003e\u003e maven-archetype-plugin:3.0.1:generate (default-cli) \u003e generate-sources @ standalone-pom \u003e\u003e\u003e\n[INFO]\n[INFO] \u003c\u003c\u003c maven-archetype-plugin:3.0.1:generate (default-cli) \u003c generate-sources @ standalone-pom \u003c\u003c\u003c\n[INFO]\n[INFO]\n[INFO] --- maven-archetype-plugin:3.0.1:generate (default-cli) @ standalone-pom ---\n[INFO] Generating project in Interactive mode\n[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)\nChoose archetype:\n...\nChoose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : sauron-plugin-archetype\nChoose archetype:\n1:  remote -\u003e com.freenow.sauron:sauron-plugin-archetype (Sauron Plugin Archetype)\nChoose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 1\n[INFO] Using property: groupId = com.free-now.sauron.plugins\nDefine value for property 'artifactId': my-plugin\n[INFO] Using property: version = 0.0.1-SNAPSHOT\n[INFO] Using property: package = com.freenow.sauron.plugins\nDefine value for property 'className': MyPlugin\nConfirm properties configuration:\ngroupId: com.free-now.sauron.plugins\nartifactId: my-plugin\nversion: 0.0.1-SNAPSHOT\npackage: com.freenow.sauron.plugins\nclassName: MyPlugin\n Y: :\n[INFO] ----------------------------------------------------------------------------\n[INFO] Using following parameters for creating project from Archetype: sauron-plugin-archetype:0.0.1-SNAPSHOT\n[INFO] ----------------------------------------------------------------------------\n[INFO] Parameter: groupId, Value: com.free-now.sauron.plugins\n[INFO] Parameter: artifactId, Value: my-plugin\n[INFO] Parameter: version, Value: 0.0.1-SNAPSHOT\n[INFO] Parameter: package, Value: com.freenow.sauron.plugins\n[INFO] Parameter: packageInPathFormat, Value: com/freenow/sauron/plugins\n[INFO] Parameter: package, Value: com.freenow.sauron.plugins\n[INFO] Parameter: version, Value: 0.0.1-SNAPSHOT\n[INFO] Parameter: groupId, Value: com.free-now.sauron.plugins\n[INFO] Parameter: className, Value: MyPlugin\n[INFO] Parameter: artifactId, Value: my-plugin\n[INFO] Project created from Archetype in dir: /Users/sergio/Documents/sauron/my-plugin\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time:  15.041 s\n[INFO] Finished at: 2019-04-08T15:10:44+02:00\n[INFO] ------------------------------------------------------------------------\n```\n\nIt will generate a new maven project that follows the structure below:\n\n![](https://github.com/freenowtech/sauron/blob/main/sauron-service/docs/sauron-plugin-structure.png)\n\nFill in the `MyPlugin.java` class with your desired logic:\n\n```java\npackage com.freenow.sauron.plugins;\n\nimport com.freenow.sauron.model.DataSet;\nimport com.freenow.sauron.properties.PluginsConfigurationProperties;\nimport org.pf4j.Extension;\n\n@Extension\npublic class MyPlugin implements SauronExtension\n{\n    @Override\n    public DataSet apply(PluginsConfigurationProperties properties, DataSet input)\n    {\n        // PLUGIN LOGIC\n\n        return input;\n    }\n}\n```\n\n#### Configuring your new Plugin\n\nIn order to provide extra configuration to your plugin, refer to [CONFIGURATION SECTION](#configuration).\nAfter your configuration has been added, it will be available to be used by your plugin in\n`PluginsConfigurationProperties` object.\nSee below an example of how you can use the configuration properties:\n\nThe following configuration provides an url to my-plugin plugin generated in step above:\n\n```yaml\nsauron:\n    plugins:\n        my-plugin:\n            url: https://my-plugin.com\n```\n\nSo in order to retrieve this configuration uses the following java code:\n\n```java\n@Extension\npublic class MyPlugin implements SauronExtension\n{\n    @Override\n    public DataSet apply(PluginsConfigurationProperties properties, DataSet input)\n    {\n        properties.getPluginConfigurationProperty(\"my-plugin\", \"url\").ifPresent(url -\u003e System.out.println(url) );\n        return input;\n    }\n}\n```\n\n#### Documenting your Plugin\n\nSauron Plugin Archetype provides a template of a README that must be filled to document what your plugin does,\ninputs, outputs and possible configuration.\n\n#### Deploying your new Plugin\n\nOnce the developing and testing process has been done, you can deploy a new version of your plugin, using the\npre-defined plugin repository (Local or Artifactory). For more details please refer to [sauron-service.yml](https://github.com/freenowtech/sauron/blob/main/sauron-service/docker/config/sauron-service.yml).\n\nThe plugin reloading process runs every **5 minutes**. To force a reloading use the `/api/v1/reload` method.\n\nCheck [Swagger Documentation](http://localhost:8080/v2/api-docs) for more information.\n\n#### Using your new Plugin\n\nOnce your plugin has been deployed and loaded by Sauron Service you can use it in a pipeline which will be then applied to new deployments.\nRefer to [Sauron Usage](#usage) for detailed information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreenowtech%2Fsauron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffreenowtech%2Fsauron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreenowtech%2Fsauron/lists"}