Sumpli has two services: sumpli-core
and sumpli-graphql
. sumpli-core
is a JWKS provider in order to allow sumpli-graphql
to directly validate JWT tokens given by sumpli-core
.
When running sumpli-core
and sumpli-graphql
with replica: 1
(in Kubernetes), everything is working perfectly.
However, when we increased replicas of both services to >1, eg. replica: 2
we started having problems with authentication;
requests with a valid JWT token from sumpli-core
we're still rejected as unauthorised
by sumpli-graphql
.
What went wrong?
sumpli-core Dockerfile
FROM python:3.6.2
RUN mkdir -p /app
WORKDIR /app
COPY requirements.txt /app
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app
EXPOSE 8000
CMD ["./start.sh"]
sumpli-core start.sh
#!/bin/bash
# Dockerfile entrypoint ["./start.sh"]
echo Running pre-flight operations...
if [ ! -f ./config/keys/privkey.pem ]; then
openssl genrsa -out ./config/keys/privkey.pem 2048
fi
...other stuff....
...start server....
sumpli-core settings
...other stuff....
# JWT
# http://getblimp.github.io/django-rest-framework-jwt/#additional-settings
with open(BASE_DIR + '/config/keys/privkey.pem', 'rb') as f:
RSA_PRIV_KEY = ser.load_pem_private_key(f.read(), password=None, backend=default_backend())
RSA_PUB_KEY = RSA_PRIV_KEY.public_key()
JWT_AUTH = {
'JWT_PAYLOAD_HANDLER': 'apps.sumpli_auth.jwt.jwt_payload_handler',
'JWT_PAYLOAD_GET_USERNAME_HANDLER': 'apps.sumpli_auth.jwt.custom_username_handler',
'JWT_ALLOW_REFRESH': True,
'JWT_ALGORITHM': 'RS256',
'JWT_PUBLIC_KEY': RSA_PUB_KEY,
'JWT_PRIVATE_KEY': RSA_PRIV_KEY,
'JWT_AUDIENCE': 'urn:sumpli',
'JWT_ISSUER': 'sumpli:api:production',
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=90),
}
...other stuff....
sumpli-graphql jwt.js
...other stuff....
export const jwtMiddleware = jwt({
secret: jwksRsa.koaJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 2,
jwksUri: config.JWKS_URI, <-- this points correctly to Django's JWT JWKS auth endpoint
kid: 'LATEST',
}),
audience,
issuer,
debug: true,
algorithms: ['RS256'],
passthrough: true,
tokenKey: 'jwt',
})