Skip to content

Fix TLS issues in Granian and implement TLS for NGINX#2515

Merged
crivetimihai merged 1 commit intomainfrom
fix-certificate-pass
Jan 28, 2026
Merged

Fix TLS issues in Granian and implement TLS for NGINX#2515
crivetimihai merged 1 commit intomainfrom
fix-certificate-pass

Conversation

@madhav165
Copy link
Copy Markdown
Collaborator

@madhav165 madhav165 commented Jan 27, 2026

🐛 Bug-fix PR

Closes #2526


📌 Summary

This PR focuses on fixing and documenting TLS setup issues across docker-compose, Granian, and Nginx to make HTTPS deployments work reliably.

Key Changes

  • Granian SSL fix: Added missing SSL key passphrase support in run-granian and switched to AES-256 encrypted keys, which Granian requires.
  • Nginx cert mounting: Added certificate mounts to Nginx containers.
  • Nginx SSL config: Added backend SSL configuration and optional frontend HTTPS config in nginx.conf.
  • TLS handshake error fix: Identified and fixed the cause of InvalidContentType handshake errors by correcting Nginx HTTPS configuration and connection reuse.
  • TLS documentation: Added a detailed TLS guide with setup options, fixes, and debugging info (including peer address errors like 172.18.0.X:XXXXX).

Impact

  • HTTPS now works end-to-end (gateway ↔ nginx ↔ client)
  • TLS errors are eliminated after config update
  • Clear documentation reduces setup and debugging time
  • No breaking changes (TLS remains opt-in)

🧪 Verification

Check Command Status
Lint suite make lint pass
Unit tests make test pass

📐 MCP Compliance (if relevant)

  • Matches current MCP spec
  • No breaking change to MCP clients

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • No secrets/credentials committed

@madhav165 madhav165 changed the title Fix TLS for self signed certificates with passphrase on granian and implement TLS for NGINX Fix TLS issues in Granian and implement TLS for NGINX Jan 27, 2026
@madhav165 madhav165 force-pushed the fix-certificate-pass branch from 1b9fdc3 to 7d94526 Compare January 27, 2026 14:30
@madhav165 madhav165 linked an issue Jan 27, 2026 that may be closed by this pull request
7 tasks
@madhav165 madhav165 marked this pull request as draft January 27, 2026 15:46
@madhav165 madhav165 marked this pull request as ready for review January 27, 2026 17:09
@crivetimihai
Copy link
Copy Markdown
Member

Review and Fixes Applied

I've rebased this PR onto main and made the following corrections:

Bug Fix

  • Fixed broken certs Makefile target - The shell script was incomplete (missing -addext "subjectAltName=...", closing semicolon, success message, and fi). This would have caused certificate generation to fail.

Reverted Unintended Changes

Removed leaked local development settings that were not related to TLS:

  • Restored HTTP_SERVER=gunicorn as default (was changed to granian)
  • Restored GRANIAN_WORKERS=16 (was reduced to 2)
  • Restored replicas: 3 (was reduced to 1)
  • Restored resource limits to production defaults (8G/4G instead of 2G/1G)
  • Restored gateway ports as commented out (for multi-replica mode)

Commit History

Squashed 12 commits into 1 clean commit with proper conventional commit format and co-author attribution.

Verification

  • ✅ Package verification passed (10/10)
  • ✅ Makefile syntax validated
  • ✅ Security review passed (no injection vulnerabilities, proper file permissions)
  • ✅ Changes are consistent with existing codebase patterns

@crivetimihai crivetimihai self-assigned this Jan 28, 2026
…figuration

- Add passphrase-protected key support for Granian via --ssl-keyfile-password
- Add KEY_FILE_PASSWORD and CERT_PASSPHRASE compatibility in run-granian.sh
- Export KEY_FILE in run-gunicorn.sh for Python SSL manager access
- Improve Makefile cert targets with proper permissions (640) and group 0
- Split certs-passphrase into two-step generation (genrsa + req) for AES-256
- Add SSL configuration templates to nginx.conf for client and backend TLS
- Expose port 443 in NGINX Dockerfile for HTTPS support
- Update docker-compose.yml with TLS-related comments and correct cert paths
- Add comprehensive TLS configuration documentation

Co-authored-by: Madhav Kandukuri <madhav165@gmail.com>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
@crivetimihai
Copy link
Copy Markdown
Member

Additional Fixes (based on code review)

Addressed two valid issues identified during review:

1. KEY_FILE path mismatch (Medium)

Issue: docker-compose.yml pointed KEY_FILE to key-encrypted.pem, but make certs only creates key.pem. Users following the compose hints would get "file not found".

Fix: Restored KEY_FILE=/app/certs/key.pem as the default, with explicit documentation for passphrase-protected keys:

## Uncomment to enable HTTPS (run `make certs` first)
# - SSL=true
# - CERT_FILE=/app/certs/cert.pem
# - KEY_FILE=/app/certs/key.pem
# For passphrase-protected keys: run `make certs-passphrase` and use:
# - KEY_FILE=/app/certs/key-encrypted.pem
# - KEY_FILE_PASSWORD=${KEY_FILE_PASSWORD}

2. nginx backend TLS guidance incomplete (Low)

Issue: The proxy_ssl_* settings could be uncommented without changing proxy_pass from http:// to https://, causing TLS handshake errors.

Fix: Added explicit instructions in the SSL Backend Configuration section:

# To enable HTTPS for backend connections to gateway:
# 1. Uncomment these proxy_ssl_* settings below
# 2. Change ALL proxy_pass directives from http:// to https://
#    (e.g., proxy_pass https://gateway_backend;)

Granian version verified

The --ssl-keyfile-password option is supported in Granian. The project requires >=2.6.1 which includes this feature.

@crivetimihai crivetimihai merged commit fec4b5f into main Jan 28, 2026
40 of 41 checks passed
@crivetimihai crivetimihai deleted the fix-certificate-pass branch January 28, 2026 12:17
hughhennelly pushed a commit to hughhennelly/mcp-context-forge that referenced this pull request Feb 8, 2026
…figuration (IBM#2515)

- Add passphrase-protected key support for Granian via --ssl-keyfile-password
- Add KEY_FILE_PASSWORD and CERT_PASSPHRASE compatibility in run-granian.sh
- Export KEY_FILE in run-gunicorn.sh for Python SSL manager access
- Improve Makefile cert targets with proper permissions (640) and group 0
- Split certs-passphrase into two-step generation (genrsa + req) for AES-256
- Add SSL configuration templates to nginx.conf for client and backend TLS
- Expose port 443 in NGINX Dockerfile for HTTPS support
- Update docker-compose.yml with TLS-related comments and correct cert paths
- Add comprehensive TLS configuration documentation

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Co-authored-by: Mihai Criveti <crivetimihai@gmail.com>
Signed-off-by: hughhennnelly <hughhennelly06@gmail.com>
kcostell06 pushed a commit to kcostell06/mcp-context-forge that referenced this pull request Feb 24, 2026
…figuration (IBM#2515)

- Add passphrase-protected key support for Granian via --ssl-keyfile-password
- Add KEY_FILE_PASSWORD and CERT_PASSPHRASE compatibility in run-granian.sh
- Export KEY_FILE in run-gunicorn.sh for Python SSL manager access
- Improve Makefile cert targets with proper permissions (640) and group 0
- Split certs-passphrase into two-step generation (genrsa + req) for AES-256
- Add SSL configuration templates to nginx.conf for client and backend TLS
- Expose port 443 in NGINX Dockerfile for HTTPS support
- Update docker-compose.yml with TLS-related comments and correct cert paths
- Add comprehensive TLS configuration documentation

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Co-authored-by: Mihai Criveti <crivetimihai@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Gateway Container Stuck at "Waiting" with SSL Enabled

2 participants