Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Reference architecture and proof of concept implementation for supply chain security gateway

License

Notifications You must be signed in to change notification settings

abhisek/supply-chain-security-gateway

Repository files navigation

Archived: This project is now developed at https://github.com/safedep/gateway

Supply Chain Security Gateway

A reference architecture and proof of concept implementation of a supply chain security gateway with the goal of enforcing sane security policies to an organization's consumption of 3rd party software (dependencies) in its own products.

TL;DR

Ensure git submodules are updated locally

git submodule update --init --recursive

Initialize keys and certificates for mTLS

./bootstrap.sh

This will generate root certificate, per service certificates in pki/.

TLS SAN must be correctly set in the generated certificate for the mTLS to work correctly. Verify using:

openssl x509 -noout -text \
  -in ./pki/nats-server/server.crt | grep "DNS:nats-server"

Start the services using docker-compose

docker-compose up -d

Verify all the services are active

docker-compose ps

Use the gateway using a demo-client

cd demo-clients/java-gradle && ./gradlew assemble --refresh-dependencies

At this point, you should see logs generated by gateway and the policy decision service and multiple artefacts that are violating configured policy are blocked by the gateway

docker-compose logs envoy
docker-compose logs pdp

The gradle build should fail with an error message indicating a dependency was blocked by the gateway.

> Could not resolve all files for configuration ':app:compileClasspath'.
   > Could not resolve org.apache.logging.log4j:log4j:2.16.0.
     Required by:
         project :app
      > Could not resolve org.apache.logging.log4j:log4j:2.16.0.
         > Could not get resource 'http://localhost:10000/maven2/org/apache/logging/log4j/log4j/2.16.0/log4j-2.16.0.pom'.
            > Could not GET 'http://localhost:10000/maven2/org/apache/logging/log4j/log4j/2.16.0/log4j-2.16.0.pom'. Received status code 403 from server: Forbidden

Refer to policies/example.rego for the policy that blocked this artefact

Edit config/global.yml and set pdp.monitor_mode=true to enable only monitoring and disable policy enforcement. Restart the containers for the changes to take effect.

docker-compose up --force-recreate --remove-orphans --build -d

Run the build again to see it compile successfully.

cd demo-clients/java-gradle && ./gradlew build --refresh-dependencies

Architecture

HLD

Data Plane Flow

Data Plane Flow

Usage

If you are developing on any of the service and want to force re-create the containers with updated image:

docker-compose up --force-recreate --remove-orphans --build -d

Configuring Upstream and Routes

The configuration plane is currently half baked. It needs a tool and a single source of truth to generate configuration for Envoy and Gateway. For now, look at:

  1. config/global.yml
  2. config/envoy.yml

The route definitions in envoy.yml must match the path patterns in global.yml

Configuring Environments

To use the gateway in a CI or developer local environment, package managers need to be configured to use the gateway URL and credentials as repository.

PacMan makes it easy to automatically configure an environment to use the gateway for downloading 3rd party dependencies.

Authentication

There are two authentication points:

  1. Ingress
  2. Egress

Ingress authentication is for incoming requests to the gateway and can be used to identify who is accessing the gateway.

Egress authentication is for upstream repositories, especially the ones that need authentication e.g. CodeArtifact, JFrog, Nexus etc.

Ingress Authentication

Basic Authentication

Use htpasswd to add users:

htpasswd -nbB user1 password1 >> ./config/gateway-auth-basic

Enable authentication for upstream in config/global.yml

Development

PDP Development

Build and run the PDP using:

cd services && make
GLOBAL_CONFIG_PATH=../config/global.yml PDP_POLICY_PATH=../policies ./out/pdp-server

PDP listens on 0.0.0.0:9000. To use the host instance of PDP, edit config/envoy.yml and set the address of the ExtAuthZ plugin to your host network address.

Policy Development

Policies are written in Rego and evaluated with Open Policy Agent

To run policy test cases:

cd policies && make test
  • Refer to policies/example.rego for policy example
  • Policies are load from ./policies directory

Tap Development

The Tap Service is integrated as a Envoy ExtProc filter. This means, it has greater control over Envoy's request processing life-cycle and can make changes if required.

Currently, it is used for publishing events for data collection only but in future may be extended to support other use-cases. Tap service internally implements a handler chain to delegate an Envoy event to its internal handlers. Example:

tapService, err := tap.NewTapService(config, []tap.TapHandlerRegistration{
  tap.NewTapEventPublisherRegistration(),
})

To build and use from host:

cd services && make
GLOBAL_CONFIG_PATH=../config/global.yml ./out/tap-server

To use Tap service from host, edit envoy.yml and change address of ext-proc-tap cluster.

Debug NATS Messaging

Start a docker container with nats client

docker run --rm -it \
   --network supply-chain-security-gateway_default \
   -v `pwd`:/workspace \
   synadia/nats-box

Subscribe to a subject and receive messages

GODEBUG=x509ignoreCN=0 nats sub \
   --tlscert=/workspace/pki/tap/server.crt \
   --tlskey=/workspace/pki/tap/server.key \
   --tlsca=/workspace/pki/root.crt \
   --server=tls://nats-server:4222 \
   com.msg.event.upstream.request

Contribution

Look at Github issues

About

Reference architecture and proof of concept implementation for supply chain security gateway

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published