From d56bf7571d9f90af5f7d2b77531fa42f8c070e7b Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 11:51:04 +0000 Subject: [PATCH 01/19] Move active_usernames example file to project root dir #28 --- .../active_usernames.example.txt => active_usernames.example.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ldap_jwt_auth/active_usernames.example.txt => active_usernames.example.txt (100%) diff --git a/ldap_jwt_auth/active_usernames.example.txt b/active_usernames.example.txt similarity index 100% rename from ldap_jwt_auth/active_usernames.example.txt rename to active_usernames.example.txt From 2200ed616741c07edbc5b5e4c15bbcdb7cc7f6b0 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 11:52:15 +0000 Subject: [PATCH 02/19] Create a logs dir in the project root dir #28 --- logs/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 logs/.keep diff --git a/logs/.keep b/logs/.keep new file mode 100644 index 0000000..e69de29 From 1d0a0b9788007e7a1a5dc9934463e7804c1aedb7 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 11:53:30 +0000 Subject: [PATCH 03/19] Update .env example file #28 --- ldap_jwt_auth/.env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ldap_jwt_auth/.env.example b/ldap_jwt_auth/.env.example index 9239f3f..71d5293 100644 --- a/ldap_jwt_auth/.env.example +++ b/ldap_jwt_auth/.env.example @@ -7,6 +7,6 @@ AUTHENTICATION__PUBLIC_KEY_PATH=./keys/jwt-key.pub AUTHENTICATION__JWT_ALGORITHM=RS256 AUTHENTICATION__ACCESS_TOKEN_VALIDITY_MINUTES=5 AUTHENTICATION__REFRESH_TOKEN_VALIDITY_DAYS=7 -AUTHENTICATION__ACTIVE_USERNAMES_PATH=./ldap_jwt_auth/active_usernames.txt +AUTHENTICATION__ACTIVE_USERNAMES_PATH=./active_usernames.txt LDAP_SERVER__URL=ldap://ldap.example.com:389 LDAP_SERVER__REALM=LDAP.EXAMPLE.COM From 762a4e13db2cbb5ae71c7b1ce90b1bfb6cbe9e93 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 11:53:44 +0000 Subject: [PATCH 04/19] Update logging example file #28 --- ldap_jwt_auth/logging.example.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ldap_jwt_auth/logging.example.ini b/ldap_jwt_auth/logging.example.ini index 28dc765..bf5f3e3 100644 --- a/ldap_jwt_auth/logging.example.ini +++ b/ldap_jwt_auth/logging.example.ini @@ -22,7 +22,7 @@ propagate=0 [handler_fileHandler] class=logging.handlers.TimedRotatingFileHandler formatter=fileFormatter -args=('ldap-jwt-auth.log', 'D', 1, 20,) +args=('./logs/ldap-jwt-auth.log', 'D', 1, 20,) [handler_consoleHandler] class=StreamHandler From 1ef9f118fce5721f532232cd365de528ca678531 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 11:55:19 +0000 Subject: [PATCH 05/19] Upgrade python base image in Dockerfile #28 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 169b8d7..82caadf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.10-alpine3.17 +FROM python:3.10-alpine3.19 WORKDIR /ldap-jwt-auth-run From ad62fb6b4e4af1969cd286d0fba5bfccb6927b1d Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 11:55:44 +0000 Subject: [PATCH 06/19] Copy logs dir in Dockerfile #28 --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 82caadf..9e0bff8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ WORKDIR /ldap-jwt-auth-run COPY pyproject.toml ./ COPY ldap_jwt_auth/ ldap_jwt_auth/ +COPY logs/ logs/ RUN --mount=type=cache,target=/root/.cache \ set -eux; \ From b166c070c2d55649dccbf6c4e818c0e4f92c6098 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:04:18 +0000 Subject: [PATCH 07/19] Update volumes in docker-compose.yml #28 --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 4c3bbc9..e872276 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,6 +7,8 @@ services: volumes: - ./ldap_jwt_auth:/ldap-jwt-auth-run/ldap_jwt_auth - ./keys:/ldap-jwt-auth-run/keys + - ./logs:/ldap-jwt-auth-run/logs + - ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt ports: - 8000:8000 restart: on-failure From ff90cdde30dc0e147d8567544ae9e0f4fa29faa3 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:05:46 +0000 Subject: [PATCH 08/19] Configure root_path of FastAPI object #28 --- ldap_jwt_auth/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ldap_jwt_auth/main.py b/ldap_jwt_auth/main.py index 3731375..40debc9 100644 --- a/ldap_jwt_auth/main.py +++ b/ldap_jwt_auth/main.py @@ -14,7 +14,7 @@ from ldap_jwt_auth.core.logger_setup import setup_logger from ldap_jwt_auth.routers import login, refresh, verify -app = FastAPI(title=config.api.title, description=config.api.description) +app = FastAPI(title=config.api.title, description=config.api.description, root_path=config.api.root_path) setup_logger() logger = logging.getLogger() From c2c505b3f35ea76a94cb3bbb3121da37ce00f7ed Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:05:57 +0000 Subject: [PATCH 09/19] Update .gitignore #28 --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7230ad4..657396f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ ldap_jwt_auth/logging.ini -ldap_jwt_auth/active_usernames.txt +/active_usernames.txt /keys/ # Byte-compiled / optimized / DLL files From 1756dffb088ed8e176f06aec6eb46d7519648e8d Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:06:59 +0000 Subject: [PATCH 10/19] Create a production Dockerfile #28 --- Dockerfile.prod | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Dockerfile.prod diff --git a/Dockerfile.prod b/Dockerfile.prod new file mode 100644 index 0000000..7b08d30 --- /dev/null +++ b/Dockerfile.prod @@ -0,0 +1,43 @@ +FROM python:3.10-alpine3.19 + +WORKDIR /ldap-jwt-auth-run + +COPY README.md pyproject.toml ./ +# Copy ldap_jwt_auth source files +COPY ldap_jwt_auth/ ldap_jwt_auth/ +COPY logs/ logs/ + +RUN set -eux; \ + \ + # Install python-ldap system dependencies \ + apk add --no-cache build-base openldap-dev python3-dev; \ + \ + # Install pip dependencies \ + python -m pip install --no-cache-dir .; \ + \ + # Create loging.ini from its .example file \ + cp ldap_jwt_auth/logging.example.ini ldap_jwt_auth/logging.ini; \ + \ + # Create a non-root user to run as \ + addgroup -S ldap-jwt-auth; \ + adduser -S -D -G ldap-jwt-auth -H -h /ldap-jwt-auth-run ldap-jwt-auth; \ + \ + # Change ownership of logs/ - app will need to write log files to it \ + chown -R ldap-jwt-auth:ldap-jwt-auth logs/ + +USER ldap-jwt-auth + +ENV API__TITLE="LDAP-JWT Authentication Service API" +ENV API__DESCRIPTION="This is the API for the LDAP-JWT Authentication Service" +ENV API__ROOT_PATH="" +ENV AUTHENTICATION__PRIVATE_KEY_PATH="./keys/jwt-key" +ENV AUTHENTICATION__PUBLIC_KEY_PATH="./keys/jwt-key.pub" +ENV AUTHENTICATION__JWT_ALGORITHM="RS256" +ENV AUTHENTICATION__ACCESS_TOKEN_VALIDITY_MINUTES=5 +ENV AUTHENTICATION__REFRESH_TOKEN_VALIDITY_DAYS=7 +ENV AUTHENTICATION__ACTIVE_USERNAMES_PATH="./active_usernames.txt" +ENV LDAP_SERVER__URL="ldap://ldap.example.com:389" +ENV LDAP_SERVER__REALM="LDAP.EXAMPLE.COM" + +CMD ["uvicorn", "ldap_jwt_auth.main:app", "--host", "0.0.0.0", "--port", "8000"] +EXPOSE 8000 From 4694d4d18d59ac569ffef428516faca2ab2ebde7 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:21:13 +0000 Subject: [PATCH 11/19] Configure CI job to build and push image to Harbor #28 --- .github/workflows/.ci.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/.github/workflows/.ci.yml b/.github/workflows/.ci.yml index 63ec332..9c00c1c 100644 --- a/.github/workflows/.ci.yml +++ b/.github/workflows/.ci.yml @@ -63,3 +63,35 @@ jobs: - name: Run unit tests run: pytest -c test/pytest.ini test/unit/ --cov + + docker: + # This job triggers only if all the other jobs succeed. It builds the Docker image and if successful, + # it pushes it to Harbor. + needs: [linting, unit-tests] + name: Docker + runs-on: ubuntu-latest + steps: + - name: Check out repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Login to Harbor + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + registry: harbor.stfc.ac.uk/inventory-management-system + username: ${{ secrets.HARBOR_USERNAME }} + password: ${{ secrets.HARBOR_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 + with: + images: harbor.stfc.ac.uk/inventory-management-system/auth-api + + - name: Build and push Docker image to Harbor + uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 + with: + context: . + file: ./Dockerfile.prod + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 679ed877ad7d15ca4f1f43e06b76c2d85ac825a9 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:02:34 +0000 Subject: [PATCH 12/19] Create ldap-jwt-auth group and user with ID #28 --- Dockerfile.prod | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index 7b08d30..c055077 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -19,11 +19,11 @@ RUN set -eux; \ cp ldap_jwt_auth/logging.example.ini ldap_jwt_auth/logging.ini; \ \ # Create a non-root user to run as \ - addgroup -S ldap-jwt-auth; \ - adduser -S -D -G ldap-jwt-auth -H -h /ldap-jwt-auth-run ldap-jwt-auth; \ + addgroup -g 500 -S ldap-jwt-auth; \ + adduser -S -D -G ldap-jwt-auth -H -u 500 -h /ldap-jwt-auth-run ldap-jwt-auth; \ \ # Change ownership of logs/ - app will need to write log files to it \ - chown -R ldap-jwt-auth:ldap-jwt-auth logs/ + chown -R ldap-jwt-auth:ldap-jwt-auth logs/; USER ldap-jwt-auth From 67e599228c99619212a06b47833523c1e356d751 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Mon, 12 Feb 2024 12:04:22 +0000 Subject: [PATCH 13/19] Fix samesite and path cookie attributes #28 --- ldap_jwt_auth/routers/login.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ldap_jwt_auth/routers/login.py b/ldap_jwt_auth/routers/login.py index 61d87f6..a152e67 100644 --- a/ldap_jwt_auth/routers/login.py +++ b/ldap_jwt_auth/routers/login.py @@ -47,8 +47,8 @@ def login( max_age=config.authentication.refresh_token_validity_days * 24 * 60 * 60, secure=True, httponly=True, - samesite="Lax", - path="/refresh", + samesite="lax", + path=f"{config.api.root_path}/refresh", ) return response except (InvalidCredentialsError, UserNotActiveError) as exc: From 6f196f7658c9e792bc2dc61bf41090e0da5ad1bf Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Mon, 12 Feb 2024 14:35:28 +0000 Subject: [PATCH 14/19] Update README #28 --- README.md | 135 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 113 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 434b346..361d8ef 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,52 @@ # LDAP-JWT Authentication Service -This is a Python microservice that provides user authentication against an LDAP server and returns a JSON Web Token -(JWT). + +This is a Python microservice created using FastAPI that provides user authentication against an LDAP server and returns +a JSON Web Token (JWT). ## How to Run This microservice requires an LDAP server to run against. ### Prerequisites -- Docker installed (if you want to run the microservice inside Docker) -- Python 3.10 (or above) and an LDAP server to connect to +- Docker and Docker Compose installed (if you want to run the microservice inside Docker) +- LDAP server to connect to +- Python 3.10 (or above) (if you are not using Docker) - Private and public key pair (must be OpenSSH encoded) for encrypting and decrypting the JWTs +- A list of active usernames, defining who can use this service - This repository cloned ### Docker Setup -The easiest way to run the application with Docker for local development is using the `docker-compose.yml` file. It is -configured to start the application in a reload mode using the `Dockerfile`. You can also use the `Dockerfile` directly -to run the application in a container. Please do not use the `Dockerfile` in production. - Ensure that Docker is installed and running on your machine before proceeding. -1. Create a `.env` file alongside the `.env.example` file. Use the example file as a reference and modify the values accordingly. +1. Create a `.env` file alongside the `.env.example` file. Use the example file as a reference and modify the values + accordingly. + ```bash + cp ldap_jwt_auth/.env.example ldap_jwt_auth/.env + ``` -2. Create a `logging.ini` file alongside the `logging.example.ini` file. Use the example file as a reference and modify it accordingly. +2. Create a `logging.ini` file alongside the `logging.example.ini` file. Use the example file as a reference and modify + it accordingly: + ```bash + cp ldap_jwt_auth/logging.example.ini ldap_jwt_auth/logging.ini + ``` -3. Create a `keys` directory in the root of the project directory, navigate to it, and generate OpenSSH encoded private and public key pair: +3. Create a `keys` directory in the root of the project directory, navigate to it, and generate OpenSSH encoded private + and public key pair: ```bash mkdir keys cd keys/ - ssh-keygen -b 2048 -t rsa -f jwt-key -q -N "" + ssh-keygen -b 2048 -t rsa -f jwt-key -q -N "" -C "" + ``` + +4. Create a `active_usernames.txt` file alongside the `active_usernames.example.txt` file and add all the usernames that + can use this system. The usernames are the Federal IDs and each one should be stored on a separate line. + ```bash + cp active_usernames.example.txt active_usernames.txt ``` -4. Create a `active_usernames.txt` file alongside the `active_usernames.example.txt` file and add all the usernames (each one on a seperate line) that are active/can access the system. +#### Using `docker-compose.yml` +The easiest way to run the application with Docker for local development is using the `docker-compose.yml` file. It is +configured to start the application in a reload mode using the `Dockerfile`. -#### Using Docker Compose File 1. Build and start the Docker container: ```bash docker-compose up @@ -39,7 +54,10 @@ Ensure that Docker is installed and running on your machine before proceeding. The microservice should now be running inside Docker at http://localhost:8000 and its Swagger UI could be accessed at http://localhost:8000/docs. -#### Using Dockerfile +#### Using `Dockerfile` +Use the `Dockerfile` to run just the application itself in a container. Use this only for local development (not +production)! + 1. Build an image using the `Dockerfile` from the root of the project directory: ```bash docker build -f Dockerfile -t ldap_jwt_auth_image . @@ -47,13 +65,51 @@ Ensure that Docker is installed and running on your machine before proceeding. 2. Start the container using the image built and map it to port `8000` locally: ```bash - docker run -p 8000:8000 --name ldap_jwt_auth_container ldap_jwt_auth_image + docker run -p 8000:8000 --name ldap_jwt_auth_container -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_image + ``` + or with values for the environment variables: + ```bash + docker run -p 8000:8000 --name ldap_jwt_auth_container --env AUTHENTICATION__ACCESS_TOKEN_VALIDITY_MINUTES=10 -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_image + ``` + The microservice should now be running inside Docker at http://localhost:8000 and its Swagger UI could be accessed + at http://localhost:8000/docs. + +#### Using `Dockerfile.prod` +Use the `Dockerfile.prod` to run just the application itself in a container. This can be used for production. + +1. While in root of the project directory, change the permissions of the `logs` directory so that it is writable by + other users. This allows the container to save the application logs to it. + ```bash + sudo chmod -R 0777 logs/ + ``` + +2. Private keys are only readable by the owner. Given that the private key is generated on the host machine and the + container runs with a different user, it means that the key is not readable by the user in the container because the + ownership belongs to the user on the host. This can be solved by transferring the ownership to the user in the + container and setting the permissions. + ```bash + sudo chown 500:500 keys/jwt-key + sudo chmod 0400 keys/jwt-key + ``` + +3. Build an image using the `Dockerfile.prod` from the root of the project directory: + ```bash + docker build -f Dockerfile.prod -t ldap_jwt_auth_image . + ``` + +4. Start the container using the image built and map it to port `8000` locally: + ```bash + docker run -p 8000:8000 --name ldap_jwt_auth_container -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_image + ``` + or with values for the environment variables: + ```bash + docker run -p 8000:8000 --name ldap_jwt_auth_container --env AUTHENTICATION__ACCESS_TOKEN_VALIDITY_MINUTES=10 -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_image ``` The microservice should now be running inside Docker at http://localhost:8000 and its Swagger UI could be accessed at http://localhost:8000/docs. ### Local Setup -Ensure that you have an LDAP server to connect to. +Ensure that Python is installed on your machine before proceeding. 1. Create a Python virtual environment and activate it in the root of the project directory: ```bash @@ -68,21 +124,31 @@ Ensure that you have an LDAP server to connect to. ```bash pip install .[dev] ``` - 4. Create a `.env` file alongside the `.env.example` file. Use the example file as a reference and modify the values accordingly. + ```bash + cp ldap_jwt_auth/.env.example ldap_jwt_auth/.env + ``` 5. Create a `logging.ini` file alongside the `logging.example.ini` file. Use the example file as a reference and modify - it accordingly. + it accordingly: + ```bash + cp ldap_jwt_auth/logging.example.ini ldap_jwt_auth/logging.ini + ``` -6. Create a `keys` directory in the root of the project directory, navigate to it, and generate OpenSSH encoded private and public key pair: +6. Create a `keys` directory in the root of the project directory, navigate to it, and generate OpenSSH encoded private + and public key pair: ```bash mkdir keys cd keys/ - ssh-keygen -b 2048 -t rsa -f jwt-key -q -N "" + ssh-keygen -b 2048 -t rsa -f jwt-key -q -N "" -C "" ``` -7. Create a `active_usernames.txt` file alongside the `active_usernames.example.txt` file and add all the usernames (each one on a seperate line) that are active/can access the system. +7. Create a `active_usernames.txt` file alongside the `active_usernames.example.txt` file and add all the usernames that + can use this system. The usernames are the Federal IDs and each one should be stored on a separate line. + ```bash + cp active_usernames.example.txt active_usernames.txt + ``` 8. Start the microservice using Uvicorn: ```bash @@ -95,3 +161,28 @@ Ensure that you have an LDAP server to connect to. ```bash pytest -c test/pytest.ini test/unit/ ``` + +## Notes + +### Application Configuration +The configuration for the application is handled +using [Pydantic Settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/). It allows for loading config +values from environment variables or the `.env` file. Please note that even when using the `.env` file, Pydantic will +still read environment variables as well as the `.env` file, environment variables will always take priority over +values loaded from the `.env` file. + +Listed below are the environment variables supported by the application. + +| Environment Variable | Description | Mandatory | Default Value | +|-------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|-----------|-----------------------------------------------------------| +| `API__TITLE` | The title of the API which is added to the generated OpenAPI. | No | `LDAP-JWT Authentication Service API` | +| `API__DESCRIPTION` | The description of the API which is added to the generated OpenAPI. | No | `This is the API for the LDAP-JWT Authentication Service` | +| `API__ROOT_PATH` | (If using a proxy) The path prefix handled by a proxy that is not seen by the app. | No | ` ` | +| `AUTHENTICATION__PRIVATE_KEY_PATH` | The path to the private key to be used for encoding JWT access and refresh tokens. | Yes | | +| `AUTHENTICATION__PUBLIC_KEY_PATH` | The path to the public key to be used for decoding JWT access and refresh tokens signed by the corresponding private key. | Yes | | +| `AUTHENTICATION__JWT_ALGORITHM` | The algorithm to use to decode the JWT access and refresh tokens. | Yes | | +| `AUTHENTICATION__ACCESS_TOKEN_VALIDITY_MINUTES` | Minutes after which the JWT access token expires. | Yes | | +| `AUTHENTICATION__REFRESH_TOKEN_VALIDITY_DAYS` | Days after which the JWT refresh token expires. | Yes | | +| `AUTHENTICATION__ACTIVE_USERNAMES_PATH` | The path to the `txt` file containing the active usernames and defining who can use this service. | Yes | | +| `LDAP_SERVER__URL` | The URL to the LDAP server to connect to. | Yes | | +| `LDAP_SERVER__REALM` | The realm for the LDAP server. | Yes | | From b1ee669647336b73f98956c4ad4050b445079523 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:25:31 +0000 Subject: [PATCH 15/19] Remove env var default values from prod Dockerfile #28 --- Dockerfile.prod | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Dockerfile.prod b/Dockerfile.prod index c055077..cc15637 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -27,17 +27,5 @@ RUN set -eux; \ USER ldap-jwt-auth -ENV API__TITLE="LDAP-JWT Authentication Service API" -ENV API__DESCRIPTION="This is the API for the LDAP-JWT Authentication Service" -ENV API__ROOT_PATH="" -ENV AUTHENTICATION__PRIVATE_KEY_PATH="./keys/jwt-key" -ENV AUTHENTICATION__PUBLIC_KEY_PATH="./keys/jwt-key.pub" -ENV AUTHENTICATION__JWT_ALGORITHM="RS256" -ENV AUTHENTICATION__ACCESS_TOKEN_VALIDITY_MINUTES=5 -ENV AUTHENTICATION__REFRESH_TOKEN_VALIDITY_DAYS=7 -ENV AUTHENTICATION__ACTIVE_USERNAMES_PATH="./active_usernames.txt" -ENV LDAP_SERVER__URL="ldap://ldap.example.com:389" -ENV LDAP_SERVER__REALM="LDAP.EXAMPLE.COM" - CMD ["uvicorn", "ldap_jwt_auth.main:app", "--host", "0.0.0.0", "--port", "8000"] EXPOSE 8000 From 3f4052235f66086b440d0b5983e92029563447c6 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Tue, 13 Feb 2024 11:01:17 +0000 Subject: [PATCH 16/19] Configure CI job to push prod image to new harbor project #28 --- .github/workflows/.ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/.ci.yml b/.github/workflows/.ci.yml index 9c00c1c..4cc8323 100644 --- a/.github/workflows/.ci.yml +++ b/.github/workflows/.ci.yml @@ -77,7 +77,7 @@ jobs: - name: Login to Harbor uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 with: - registry: harbor.stfc.ac.uk/inventory-management-system + registry: harbor.stfc.ac.uk/ldap-jwt-authentication username: ${{ secrets.HARBOR_USERNAME }} password: ${{ secrets.HARBOR_TOKEN }} @@ -85,7 +85,7 @@ jobs: id: meta uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: - images: harbor.stfc.ac.uk/inventory-management-system/auth-api + images: harbor.stfc.ac.uk/ldap-jwt-authentication/auth-api - name: Build and push Docker image to Harbor uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 From aaa5fa24cf7a5d5b761dd2c70a15381111ebd84d Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Tue, 13 Feb 2024 11:01:54 +0000 Subject: [PATCH 17/19] Update README #28 --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 361d8ef..6591f6c 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,7 @@ Ensure that Docker is installed and running on your machine before proceeding. and public key pair: ```bash mkdir keys - cd keys/ - ssh-keygen -b 2048 -t rsa -f jwt-key -q -N "" -C "" + ssh-keygen -b 2048 -t rsa -f keys/jwt-key -q -N "" -C "" ``` 4. Create a `active_usernames.txt` file alongside the `active_usernames.example.txt` file and add all the usernames that From 2a18fae95d37e54e480c31b172e97be3394e21cb Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Tue, 13 Feb 2024 11:30:58 +0000 Subject: [PATCH 18/19] Update README #28 --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 6591f6c..ceed370 100644 --- a/README.md +++ b/README.md @@ -139,8 +139,7 @@ Ensure that Python is installed on your machine before proceeding. and public key pair: ```bash mkdir keys - cd keys/ - ssh-keygen -b 2048 -t rsa -f jwt-key -q -N "" -C "" + ssh-keygen -b 2048 -t rsa -f keys/jwt-key -q -N "" -C "" ``` 7. Create a `active_usernames.txt` file alongside the `active_usernames.example.txt` file and add all the usernames that From 3fbc34baa21ca17bbbfc2a895f3f585f09ca4851 Mon Sep 17 00:00:00 2001 From: VKTB <45173816+VKTB@users.noreply.github.com> Date: Tue, 13 Feb 2024 11:34:32 +0000 Subject: [PATCH 19/19] Update README #28 --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ceed370..8c7f77f 100644 --- a/README.md +++ b/README.md @@ -59,16 +59,16 @@ production)! 1. Build an image using the `Dockerfile` from the root of the project directory: ```bash - docker build -f Dockerfile -t ldap_jwt_auth_image . + docker build -f Dockerfile -t ldap_jwt_auth_api_image . ``` 2. Start the container using the image built and map it to port `8000` locally: ```bash - docker run -p 8000:8000 --name ldap_jwt_auth_container -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_image + docker run -p 8000:8000 --name ldap_jwt_auth_api_container -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_api_image ``` or with values for the environment variables: ```bash - docker run -p 8000:8000 --name ldap_jwt_auth_container --env AUTHENTICATION__ACCESS_TOKEN_VALIDITY_MINUTES=10 -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_image + docker run -p 8000:8000 --name ldap_jwt_auth_api_container --env AUTHENTICATION__ACCESS_TOKEN_VALIDITY_MINUTES=10 -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_api_image ``` The microservice should now be running inside Docker at http://localhost:8000 and its Swagger UI could be accessed at http://localhost:8000/docs. @@ -93,16 +93,16 @@ Use the `Dockerfile.prod` to run just the application itself in a container. Thi 3. Build an image using the `Dockerfile.prod` from the root of the project directory: ```bash - docker build -f Dockerfile.prod -t ldap_jwt_auth_image . + docker build -f Dockerfile.prod -t ldap_jwt_auth_api_image . ``` 4. Start the container using the image built and map it to port `8000` locally: ```bash - docker run -p 8000:8000 --name ldap_jwt_auth_container -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_image + docker run -p 8000:8000 --name ldap_jwt_auth_api_container -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_api_image ``` or with values for the environment variables: ```bash - docker run -p 8000:8000 --name ldap_jwt_auth_container --env AUTHENTICATION__ACCESS_TOKEN_VALIDITY_MINUTES=10 -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_image + docker run -p 8000:8000 --name ldap_jwt_auth_api_container --env AUTHENTICATION__ACCESS_TOKEN_VALIDITY_MINUTES=10 -v ./keys/jwt-key:/ldap-jwt-auth-run/keys/jwt-key -v ./keys/jwt-key.pub:/ldap-jwt-auth-run/keys/jwt-key.pub -v ./active_usernames.txt:/ldap-jwt-auth-run/active_usernames.txt -v ./logs:/ldap-jwt-auth-run/logs ldap_jwt_auth_api_image ``` The microservice should now be running inside Docker at http://localhost:8000 and its Swagger UI could be accessed at http://localhost:8000/docs.