Skip to content

Commit 1a28ef6

Browse files
security: Harden Docker image and CI pipeline (OWASP Docker Security compliance) (#1060)
Increase docker security
1 parent 00b32cd commit 1a28ef6

2 files changed

Lines changed: 37 additions & 9 deletions

File tree

.github/workflows/Build-Test-And-Deploy.yml

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,28 @@ jobs:
6363
- name: Set up Docker Buildx
6464
uses: docker/setup-buildx-action@v4
6565

66+
- name: Generate NuGet auth config for Docker build
67+
if: github.event_name != 'pull_request' && github.event_name != 'merge_group'
68+
env:
69+
NUGET_AUTH_TOKEN: ${{ secrets.AZURE_DEVOPS_PAT }}
70+
run: |
71+
cat > /tmp/nuget-auth.config << EOF
72+
<?xml version="1.0" encoding="utf-8"?>
73+
<configuration>
74+
<packageSources>
75+
<clear />
76+
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
77+
<add key="EssentialCSharp" value="https://pkgs.dev.azure.com/intelliTect/_packaging/EssentialCSharp/nuget/v3/index.json" />
78+
</packageSources>
79+
<packageSourceCredentials>
80+
<EssentialCSharp>
81+
<add key="Username" value="docker" />
82+
<add key="ClearTextPassword" value="${NUGET_AUTH_TOKEN}" />
83+
</EssentialCSharp>
84+
</packageSourceCredentials>
85+
</configuration>
86+
EOF
87+
6688
# Build but no push with a PR
6789
- name: Docker build (no push)
6890
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
@@ -71,6 +93,8 @@ jobs:
7193
push: false
7294
tags: temp-pr-validation
7395
file: ./EssentialCSharp.Web/Dockerfile
96+
context: .
97+
build-args: ACCESS_TO_NUGET_FEED=false
7498

7599
- name: Build Container Image
76100
if: github.event_name != 'pull_request_target' && github.event_name != 'pull_request'
@@ -80,7 +104,7 @@ jobs:
80104
file: ./EssentialCSharp.Web/Dockerfile
81105
context: .
82106
secrets: |
83-
"nuget_auth_token=${{ secrets.AZURE_DEVOPS_PAT }}"
107+
"id=nugetconfig,src=/tmp/nuget-auth.config"
84108
outputs: type=docker,dest=${{ github.workspace }}/essentialcsharpwebimage.tar
85109
cache-from: type=gha
86110
cache-to: type=gha,mode=max
@@ -90,6 +114,10 @@ jobs:
90114
name: essentialcsharpwebimage
91115
path: ${{ github.workspace }}/essentialcsharpwebimage.tar
92116

117+
- name: Clean up NuGet auth config
118+
if: always()
119+
run: rm -f /tmp/nuget-auth.config
120+
93121
deploy-development:
94122
if: github.event_name != 'pull_request_target' && github.event_name != 'pull_request'
95123
runs-on: ubuntu-latest

EssentialCSharp.Web/Dockerfile

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#syntax=docker/dockerfile:1.2
22

3-
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
3+
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled AS base
44
WORKDIR /app
55
EXPOSE 8080
66
EXPOSE 8081
77

8-
FROM node:25-bookworm-slim AS frontend-build
8+
FROM node:24-bookworm-slim AS frontend-build
99
WORKDIR /frontend/EssentialCSharp.Web
1010
COPY EssentialCSharp.Web/package.json EssentialCSharp.Web/package-lock.json ./
1111
RUN npm ci
@@ -15,20 +15,20 @@ RUN npm run build
1515
FROM mcr.microsoft.com/dotnet/sdk:10.0.203 AS build
1616
ARG ACCESS_TO_NUGET_FEED=true
1717
ENV ACCESS_TO_NUGET_FEED=$ACCESS_TO_NUGET_FEED
18-
RUN sh -c "$(curl -fsSL https://aka.ms/install-artifacts-credprovider.sh)"
1918
WORKDIR /src
2019
COPY . .
2120
COPY --from=frontend-build /frontend/EssentialCSharp.Web/wwwroot/dist ./EssentialCSharp.Web/wwwroot/dist
22-
RUN --mount=type=secret,id=nuget_auth_token \
23-
if [ "$ACCESS_TO_NUGET_FEED" = "true" ]; then \
24-
auth_token=$(cat /run/secrets/nuget_auth_token) && \
25-
export VSS_NUGET_EXTERNAL_FEED_ENDPOINTS="{\"endpointCredentials\": [{\"endpoint\":\"https://pkgs.dev.azure.com/intelliTect/_packaging/EssentialCSharp/nuget/v3/index.json\", \"password\":\"$auth_token\"}]}"; \
21+
RUN --mount=type=secret,id=nugetconfig \
22+
if [ "$ACCESS_TO_NUGET_FEED" = "true" ] && [ -f /run/secrets/nugetconfig ]; then \
23+
dotnet restore "EssentialCSharp.Web.slnx" --configfile /run/secrets/nugetconfig -p:AccessToNugetFeed=$ACCESS_TO_NUGET_FEED; \
24+
else \
25+
dotnet restore "EssentialCSharp.Web.slnx" -p:AccessToNugetFeed=$ACCESS_TO_NUGET_FEED; \
2626
fi && \
27-
dotnet restore "EssentialCSharp.Web.slnx" -p:AccessToNugetFeed=$ACCESS_TO_NUGET_FEED && \
2827
dotnet build "EssentialCSharp.Web.slnx" -c Release --no-restore -p:AccessToNugetFeed=$ACCESS_TO_NUGET_FEED -p:ReleaseDateAttribute=True -p:SkipFrontendBuild=true && \
2928
dotnet publish "EssentialCSharp.Web.slnx" -c Release -p:PublishDir=/app/publish -p:UseAppHost=false -p:SkipFrontendBuild=true --no-build
3029

3130
FROM base AS final
3231
WORKDIR /app
3332
COPY --from=build /app/publish .
33+
USER app
3434
ENTRYPOINT ["dotnet", "EssentialCSharp.Web.dll"]

0 commit comments

Comments
 (0)