Add INTERNAL_API_KEY authentication for error_log_api; update all services to send key
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# Database
|
||||
POSTGRES_HOST=localhost
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_DB=transit_db
|
||||
POSTGRES_USER_AUTH=auth_user
|
||||
POSTGRES_PASSWORD_AUTH=change_me
|
||||
POSTGRES_USER_EMPLOYEE=employee_user
|
||||
POSTGRES_PASSWORD_EMPLOYEE=change_me
|
||||
POSTGRES_USER_TRANSIT=transit_user
|
||||
POSTGRES_PASSWORD_TRANSIT=change_me
|
||||
POSTGRES_USER_LOGGER=logger_user
|
||||
POSTGRES_PASSWORD_LOGGER=change_me
|
||||
|
||||
# Auth
|
||||
JWT_SECRET=change_me_in_production
|
||||
ADMIN_USER_CODES=1234,5678
|
||||
DEV_BYPASS=0
|
||||
|
||||
# Internal service-to-service authentication
|
||||
INTERNAL_API_KEY=generate_strong_random_string_here
|
||||
|
||||
# Error Log API URL (used by services to forward errors)
|
||||
ERROR_LOG_API_URL=https://error.xtransit.testinstance.nl/error_log
|
||||
|
||||
# Monitoring UI (runtime config)
|
||||
AUTH_API=https://auth.xtransit.testinstance.nl
|
||||
EMPLOYEE_API=https://employees.xtransit.testinstance.nl
|
||||
TRANSIT_API=https://transit.xtransit.testinstance.nl
|
||||
ERROR_LOG_API=https://error.xtransit.testinstance.nl
|
||||
ADMIN_UI=https://admin.xtransit.testinstance.nl
|
||||
|
||||
# Transit API
|
||||
DEV_MOCK=0
|
||||
|
||||
# Registry
|
||||
REGISTRY_HOST=gitea.testinstance.nl
|
||||
IMAGE_NAMESPACE=sven/the-transit-project
|
||||
IMAGE_TAG=latest
|
||||
|
||||
# Portainer webhook for auto-deploy
|
||||
PORTAINER_WEBHOOK_URL=
|
||||
+4
-1
@@ -39,7 +39,10 @@ async function reportError({ partofservice, error }) {
|
||||
try {
|
||||
await fetch(ERROR_LOG_API_URL, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-internal-api-key": process.env.INTERNAL_API_KEY || "",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
service: "auth_api",
|
||||
partofservice,
|
||||
|
||||
@@ -13,6 +13,7 @@ services:
|
||||
PG_USER: ${POSTGRES_USER_LOGGER}
|
||||
PG_PASS: ${POSTGRES_PASSWORD_LOGGER}
|
||||
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
||||
INTERNAL_API_KEY: ${INTERNAL_API_KEY}
|
||||
restart: unless-stopped
|
||||
|
||||
auth_api:
|
||||
@@ -31,6 +32,7 @@ services:
|
||||
ADMIN_USER_CODES: ${ADMIN_USER_CODES}
|
||||
DEV_BYPASS: ${DEV_BYPASS:-0}
|
||||
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
||||
INTERNAL_API_KEY: ${INTERNAL_API_KEY}
|
||||
depends_on:
|
||||
- error_log_api
|
||||
restart: unless-stopped
|
||||
@@ -48,6 +50,7 @@ services:
|
||||
PG_USER: ${POSTGRES_USER_EMPLOYEE}
|
||||
PG_PASS: ${POSTGRES_PASSWORD_EMPLOYEE}
|
||||
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
||||
INTERNAL_API_KEY: ${INTERNAL_API_KEY}
|
||||
depends_on:
|
||||
- error_log_api
|
||||
restart: unless-stopped
|
||||
@@ -67,6 +70,7 @@ services:
|
||||
PG_PASS: ${POSTGRES_PASSWORD_TRANSIT}
|
||||
DEV_MOCK: ${DEV_MOCK:-0}
|
||||
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
||||
INTERNAL_API_KEY: ${INTERNAL_API_KEY}
|
||||
depends_on:
|
||||
- error_log_api
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -35,7 +35,10 @@ async function reportError({ partofservice, error }) {
|
||||
try {
|
||||
await fetch(ERROR_LOG_API_URL, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-internal-api-key": process.env.INTERNAL_API_KEY || "",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
service: "employee_api",
|
||||
partofservice,
|
||||
|
||||
+20
-2
@@ -32,6 +32,21 @@ const app = express();
|
||||
app.use(express.json({ limit: "64kb" }));
|
||||
app.use(cors());
|
||||
|
||||
const INTERNAL_API_KEY = process.env.INTERNAL_API_KEY || "";
|
||||
|
||||
function requireInternalKey(req, res, next) {
|
||||
const key = req.headers["x-internal-api-key"];
|
||||
if (!INTERNAL_API_KEY) {
|
||||
log("error", "INTERNAL_API_KEY not configured on server");
|
||||
return res.status(500).json({ error: "server misconfiguration" });
|
||||
}
|
||||
if (!key || key !== INTERNAL_API_KEY) {
|
||||
log("warn", "Unauthorized error_log attempt", { ip: req.ip, path: req.originalUrl });
|
||||
return res.status(401).json({ error: "unauthorized" });
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
const ERROR_LOG_API_URL =
|
||||
process.env.ERROR_LOG_API_URL ||
|
||||
"https://error.xtransit.testinstance.nl/error_log";
|
||||
@@ -48,7 +63,10 @@ async function reportError({ partofservice, error }) {
|
||||
try {
|
||||
await fetch(ERROR_LOG_API_URL, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-internal-api-key": process.env.INTERNAL_API_KEY || "",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
service: "error_log_api",
|
||||
partofservice,
|
||||
@@ -142,7 +160,7 @@ app.get("/health", async (_req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/error_log", async (req, res) => {
|
||||
app.post("/error_log", requireInternalKey, async (req, res) => {
|
||||
try {
|
||||
const service = req.body?.service;
|
||||
const partofservice =
|
||||
|
||||
@@ -38,7 +38,10 @@ async function reportError({ partofservice, error }) {
|
||||
try {
|
||||
await fetch(ERROR_LOG_API_URL, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-internal-api-key": process.env.INTERNAL_API_KEY || "",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
service: "transit_api",
|
||||
partofservice,
|
||||
|
||||
Reference in New Issue
Block a user