The Golyn Server is a custom-built, multi-site web server designed to host and manage multiple websites efficiently. The primary purpose of this project is to host my personal portfolio, while also supporting additional websites thanks to its robust multi-site capabilities.
This server is now in production, actively maintained and continuously improved with new features and optimizations.
- The server is primarily designed to host and serve my personal portfolio and its dedicated administration panel. It includes a multi-site architecture, allowing it to manage and host any additional websites, providing flexibility to support a variety of projects or domains under the same infrastructure.
- Multi-tenant Architecture: Handle multiple sites simultaneously. Each site is isolated with its own configuration.
- Admin Tenancy: Administrators can be assigned to manage multiple specific sites. Access is strictly isolated between managed domains.
- Dynamic Auth Providers: Centralized management of OAuth2 providers (Entra ID, Google, GitHub) allowing runtime updates via API/UI.
- API Key Management: Generate long-lived tokens with specific scopes for programmatic access and external integrations.
- Advanced Monitoring: Role-based filtered logs and platform statistics. Admins only see logs for their assigned sites.
- Flexible configuration through
.conffiles for server-level and site-specific settings. - Security settings, including HTTPS redirection and cross-origin resource sharing (CORS) policies, ensure your sites remain protected and accessible.
- Content Security Policy (CSP):
- Default policy provides a high level of security while allowing common resources (CDN for jQuery, Tailwind, Google Fonts, jsDelivr).
- Base64 Support: The default policy automatically allows
data:schemes forimg-srcandfont-src, preventing issues with embedded assets. - Per-Site Customization: Each site can define its own
content_security_policyin its.conffile to override the default server policy.
- CSRF Protection: Built-in CSRF token generation and validation for forms and API endpoints.
- Email Rate Limiting: Configurable request rate limiting per site and for email services.
- TLS/SSL Management:
- Per-domain SSL certificate handling with full chain support (
chainPath). - Automatic certificate validation and expiration checking on server startup.
- Fallback mechanisms for invalid certificates to maintain server stability.
- Support for custom CA or Let's Encrypt certificates.
- Per-domain SSL certificate handling with full chain support (
- Integrated SMTP support for sending emails through the specific endpoint.
- Each site can configure its own SMTP settings (host, port, user, password) via the site-specific
.conffile. - SMTP passwords are encrypted and stored securely using a CLI tool for key generation and encryption.
- Includes reverse proxy capabilities to forward requests to other servers or services.
- Configurable via the site-specific
.conffiles to define proxy rules, such as forwarding specific routes to backend services or external APIs. - Supports secure proxying with HTTPS and configurable headers for enhanced flexibility.
- Full JSON API: Standardized responses for easy integration with frontend frameworks (e.g.,
golyn-ui). - Dashboard Stats: Real-time overview of active sites, JWT-enabled domains, user counts, and system health.
- Self-Service: Users can manage their own active sessions and theme preferences.
- Advanced Compression:
- Brotli, deflate, Zstandard and Gzip compression support
- Content-Type aware compression
- Automatic selection of the best compression method based on client support
- Caching System:
- Server-side file caching
- Cache validation
- Configurable cache expiration
- Content Delivery:
- Optimized MIME type handling
- Smart content encoding selection
- Efficient static file serving
- Built-in endpoints for SEO essentials:
robots.txthandlingsitemap.xmlgenerationhumans.txtsupport
- Content-Type optimization for XML and text files
- Automated metadata handling
Golyn features a robust, secure, and orchestrated extension system that allows external modules (like golyn-ai) to integrate deeply with the Core.
- Orchestrated Lifecycle: Extensions register themselves using a protected handshake (
idandsecret). - Dynamic Configuration: Supports environment variable injection in configuration files (both in Core and
golyn-ai) using${VAR_NAME}syntax for secrets and environment-specific paths. - Route Sandboxing: Each extension receives a protected route group (e.g.,
/api/v1/extension/{id}/), preventing them from overwriting Core routes. - Emergency Flag: Use
--no-extensionsto disable all external modules for maintenance.
Golyn provides a centralized multi-site identity platform using standardized JWT contracts, secure cookies, and a robust OAuth2/SSO broker.
The platform supports two identity scopes to balance between Single Sign-On (SSO) convenience and strict tenant isolation:
- Global Identity (
is_global: true): The user is recognized as a single entity across the entire Golyn platform. They can log in from any configured site/host. Ideal for internal staff or cross-platform services. - Restricted Identity (
is_global: false): The user is strictly tied to specific sites. Access is denied if they try to log in from a host not present in their authorized list.- Primary Site: The site where the user was originally created.
- Allowed Sites: Additional sites explicitly granted to the user via the Admin API.
Tokens issued by Golyn follow a minimal and strict claims structure, ensuring any consumer module can trust the identity without knowing Golyn's internal logic.
| Claim | Type | Description |
|---|---|---|
sub |
UUID/String | Subject: Unique and stable user identifier. |
site_id |
UUID | Tenant/Organization: The unique site/context identifier. |
managed_sites |
Array | Multi-Tenancy: List of hosts the user is authorized to manage. |
iat |
Numeric | Issued At: Token generation timestamp. |
exp |
Numeric | Expiration: Security limit for token validity. |
iss |
String | Issuer: Always set to "Golyn". |
aud |
String | Audience: Target validation, set to "GolynPlatform". |
Security Note: Golyn acts as an Identity Provider. Domain-specific data (business roles, permissions, etc.) are forbidden within the platform JWT. The token identifies who and where, while business rules remain in the specific products.
To mitigate risks like Token Leakage in URLs or logs, Golyn uses a strictly cookie-based delivery mechanism (Backend-owned sessions):
- Access Token: Stored in a cookie with
HttpOnly,Secure, andSameSite=Laxattributes. The authentication middleware looks for it automatically. refreshToken: Stored in anHttpOnlyandSecurecookie, used exclusively to obtain new access tokens without requiring user intervention.- SSL Connection: Encrypted connection to PostgreSQL database (configurable via
ssl = true).
Note: Tokens are never included in the JSON response body to prevent access from malicious scripts (XSS). All authentication is handled transparently by the browser via secure cookies.
Golyn acts as an Identity Broker, allowing users to authenticate through their corporate or personal accounts from major providers.
- Microsoft Entra ID (antes Azure AD)
- Google (Verifica
email_verified) - GitHub (Fuerza correo
PrimaryyVerified) - Apple (Validación completa de JWT/JWKS y
email_verified) - LinkedIn (API v2)
- Facebook (Meta) (Graph API)
- Amazon (Login with Amazon)
- SalesForce (Identity API con
email_verified) - X (Twitter)
- Generic OIDC
- Redirection: Send the user to
GET /api/v1/auth/{provider}/login. - Continuity: Use the
nextparameter to specify where the user should return (e.g.,/login?next=https://your-app.com/dashboard). - Handshake: After a successful login, Golyn redirects the user to the
nextURL. Tokens are automatically set as secure cookies in the browser.
Logout is comprehensive and secure:
- Endpoint:
POST /api/v1/logout. - Actions:
- Clears
access_tokenandrefreshTokencookies (set-cookie with expiration -1). - Permanently revokes the refresh token in the database to prevent further use.
- Clears temporary OAuth2 state cookies.
- Clears
- Role Hierarchy: System based on weights (
SuperAdmin=3,Admin=2,User=1) to prevent unauthorized privilege escalation. - Granular Permissions: Fine-grained access control using
grantsanddeniesper user. - Auditing: All events (local login, OAuth2, refreshes, logout, and permission changes) are logged in
audit.auth_eventswith IP and User-Agent. - Token Rotation: Implements a rotation system that invalidates old sessions when starting new ones.
- Revocation: Administrators can revoke tokens globally per user.
- Database SSL: Support for encrypted connections to PostgreSQL with CA verification.
Golyn is designed with a "Security First" approach. Our production configuration consistently achieves an A+ rating on SSL Labs, thanks to:
- Enforced HSTS (HTTP Strict Transport Security) with preloading.
- TLS 1.3 and TLS 1.2 only (legacy protocols disabled).
- High-grade cipher suites with Forward Secrecy.
- Optimized Elliptic Curve certificates.
| Endpoint | Method | Description |
|---|---|---|
/login |
POST |
Local Login: Authenticate (Sets secure cookies). |
/logout |
POST |
Logout: Revoke tokens and clear cookies. |
/refresh_token |
POST |
Token Refresh: Rotates cookies (Returns 204 No Content). |
/auth/me |
GET |
Profile: Get current authenticated user details. |
/auth/sessions |
GET/DELETE |
Self-Service: Manage your own active sessions. |
/user/theme |
GET/PUT |
Theme: Manage user interface preferences. |
/auth/:provider/login |
GET |
OAuth2 Login: Initiate SSO flow. |
/csrf-token |
GET |
Security: Obtain a fresh CSRF token (Required for mutable requests). |
/send-mail |
POST |
Communication: Send emails (Requires CSRF & Rate limited). |
/ping |
GET |
Health Check: Verify server status. |
/version |
GET |
Version: Current build information. |
Golyn includes a protected API for platform management, allowing administrators to manage sites and users programmatically. All admin endpoints require a JWT with SuperAdmin or Admin roles.
Golyn implements a strict hierarchical role system based on weights to ensure that lower-level users cannot manage higher-level ones.
| Role | Weight | Description |
|---|---|---|
superadmin |
3 | Full platform authority. Can change user roles and manage anyone. |
admin |
2 | Operational management. Can manage user accounts but not other Admins or SuperAdmins. |
user |
1 | Base role. No administrative access by default. Requires explicit grants. |
Management Rules:
- Actor > Target: An administrator can only edit, delete, or manage permissions for users with a strictly lower weight.
- Role Assignment: When creating or updating a user, the actor can only assign roles with a lower weight than their own (except SuperAdmin).
For users with the user role, access to the /admin API is delegated through specific permissions:
- Users:
users.view,users.create,users.update,users.delete,users.manage. - Sites:
sites.view,sites.create,sites.update,sites.delete. - System:
system.logs,system.stats,system.info.
Permissions are evaluated using a "Deny First" policy: if a permission is in the denies list, access is blocked even if it exists in grants.
| Endpoint | Method | Description |
|---|---|---|
/sites |
POST |
Create Site: Register a new tenant. |
/sites |
GET |
List Sites: Retrieve all registered organizations. |
/sites/configurations |
GET |
Site Configs: View technical settings for accessible sites. |
/sites/:key/configuration |
GET |
Site Detail: Full technical config for a specific site. |
/sites/:key |
DELETE |
Delete Site: Remove a site and its configurations. |
/sites/:key/status |
PATCH |
Update Site Status: Enable or disable a site. |
/users |
POST |
Create User: Add a user to a site. |
/users |
GET |
List Users: List all users or filter by site_key. |
/users/:username |
DELETE |
Delete User: Remove a user account. |
/users/:username/status |
PATCH |
Update Status: Change user account status. |
/users/:username/role |
PUT |
Update Role: Change user administrative privileges. |
/users/:username/permissions |
GET/PUT |
Manage Permissions: Get or update specific user grants/denies. |
/users/:username/sites |
GET/POST |
Multi-site: Manage sites assigned to an administrator. |
/users/:username/allowed-sites |
GET/POST |
Isolation: Manage sites allowed for a restricted user. |
/users/:username/allowed-sites/:key |
DELETE |
Isolation: Revoke site access for a restricted user. |
/users/:username/remove-allowed-sites |
POST |
Isolation: Bulk remove sites from a user. |
/sites/:key/allowed-users |
POST |
Isolation: Bulk assign users to a specific site. |
/sites/:key/remove-allowed-users |
POST |
Isolation: Bulk remove users from a site. |
/tokens |
GET/POST |
API Keys: Manage long-lived tokens for integrations. |
/sessions/active |
GET/DELETE |
Active Sessions: Monitor and terminate active system sessions. |
/auth/providers |
GET/PUT |
Auth Providers: Configure OAuth2 credentials at runtime. |
/security/policies |
GET |
Policies: View effective CSP and Rate Limit policies. |
/logs |
GET |
System Logs: View server/DB logs (filtered for Admins). |
/stats |
GET |
Platform Stats: Overview of users, sites and system health. |
/server/configuration |
GET |
Server Config: Global technical settings (SuperAdmin only). |
To run Golyn correctly, especially in production environments, you need to define the following environment variables. These variables handle sensitive information like database passwords, JWT secrets, and OAuth2 credentials.
| Variable | Description | Example / Note |
|---|---|---|
GOLYN_DB_PASSWORD |
Password for the PostgreSQL database user. | your_db_password |
GOLYN_JWT_SECRET |
Secret key used to sign and verify JWT tokens. | Use a long, random string. |
GOOGLE_CLIENT_ID |
Client ID for Google OAuth2 integration. | xxx-yyy.apps.googleusercontent.com |
GOOGLE_CLIENT_SECRET |
Client Secret for Google OAuth2 integration. | GOCSPX-xxxxxx |
GOOGLE_REDIRECT_URL |
Callback URL for Google OAuth2. | https://your-domain.com/api/v1/auth/google/callback |
AZURE_CLIENT_ID |
Client ID for Microsoft Entra ID (antes Azure AD). | your-azure-app-id |
AZURE_CLIENT_SECRET |
Client Secret for Microsoft Entra ID. | your-azure-secret |
AZURE_TENANT_ID |
Tenant ID for your Microsoft Entra ID organization. | your-tenant-id |
AZURE_REDIRECT_URL |
Callback URL for Microsoft Entra ID OAuth2. | https://your-domain.com/api/v1/auth/azure/callback |
GITHUB_CLIENT_ID |
Client ID for GitHub OAuth2 integration. | github_client_id |
GITHUB_CLIENT_SECRET |
Client Secret for GitHub OAuth2. | github_client_secret |
GITHUB_REDIRECT_URL |
Callback URL for GitHub OAuth2. | https://your-domain.com/api/v1/auth/github/callback |
APPLE_CLIENT_ID |
Client ID for Apple OAuth2. | your-apple-id |
APPLE_CLIENT_SECRET |
Client Secret for Apple OAuth2. | your-apple-secret |
APPLE_REDIRECT_URL |
Callback URL for Apple OAuth2. | https://your-domain.com/api/v1/auth/apple/callback |
X_CLIENT_ID |
Client ID for X (Twitter) OAuth2. | your-x-id |
X_CLIENT_SECRET |
Client Secret for X (Twitter) OAuth2. | your-x-secret |
X_REDIRECT_URL |
Callback URL for X OAuth2. | https://your-domain.com/api/v1/auth/x/callback |
OIDC_CLIENT_ID |
Client ID for Generic OIDC. | your-oidc-id |
OIDC_CLIENT_SECRET |
Client Secret for Generic OIDC. | your-oidc-secret |
OIDC_REDIRECT_URL |
Callback URL for OIDC. | https://your-domain.com/api/v1/auth/oidc/callback |
LINKEDIN_CLIENT_ID |
Client ID for LinkedIn OAuth2. | linkedin_id |
LINKEDIN_CLIENT_SECRET |
Client Secret for LinkedIn OAuth2. | linkedin_secret |
LINKEDIN_REDIRECT_URL |
Callback URL for LinkedIn OAuth2. | https://your-domain.com/api/v1/auth/linkedin/callback |
FACEBOOK_CLIENT_ID |
Client ID for Facebook OAuth2. | facebook_id |
FACEBOOK_CLIENT_SECRET |
Client Secret for Facebook OAuth2. | facebook_secret |
FACEBOOK_REDIRECT_URL |
Callback URL for Facebook OAuth2. | https://your-domain.com/api/v1/auth/facebook/callback |
AMAZON_CLIENT_ID |
Client ID for Amazon OAuth2. | amazon_id |
AMAZON_CLIENT_SECRET |
Client Secret for Amazon OAuth2. | amazon_secret |
AMAZON_REDIRECT_URL |
Callback URL for Amazon OAuth2. | https://your-domain.com/api/v1/auth/amazon/callback |
SALESFORCE_CLIENT_ID |
Client ID for SalesForce OAuth2. | salesforce_id |
SALESFORCE_CLIENT_SECRET |
Client Secret for SalesForce OAuth2. | salesforce_secret |
SALESFORCE_REDIRECT_URL |
Callback URL for SalesForce OAuth2. | https://your-domain.com/api/v1/auth/salesforce/callback |
GOLYN_AI_SECRET |
Secret key for the Golyn-AI extension handshake. | Required if golyn-ai is enabled. |
GOLYN_KEY_PHRASE |
Key phrase used as salt/integrity check for password encryption. | Used for AES-256-GCM credentials protection. |
GOLYN_SECRET_KEY |
Master secret key for encrypting/decrypting sensitive data. | 32-character string for AES-256. |
SMTP_SITE_PASS |
Encrypted SMTP password for a specific site. | Replace SITE with your site name (e.g., SMTP_PORTFOLIO_PASS). |
Tip: You can define these variables in a
.envfile at the project root or directly in your system's environment. Golyn will automatically expand these variables when they are referenced in the.conffiles using the${VARIABLE_NAME}syntax.
Security secrets and provider credentials must be defined via environment variables.
# config/server/web_server.conf
[database]
ssl = true
sslRootCert = ./certificates/db/postgres/root.crt
[server]
tokenExpirationTime = 5 # Access Token duration (minutes)
tokenExpirationRefreshTime = 1440 # Refresh Token duration (minutes)
jwtSecret = ${GOLYN_JWT_SECRET}Add your provider credentials to the configuration and the .env file:
[oauth2.azure]
enabled = true
client_id = ${AZURE_CLIENT_ID}
client_secret = ${AZURE_CLIENT_SECRET}
tenant_id = ${AZURE_TENANT_ID}
redirect_url = https://your-domain.com/api/v1/auth/azure/callbackThe AuthMiddleware() validates the token and injects the subject and site_id into the Gin context.
private := router.Group("/api/v1/private", middlewares.AuthMiddleware())
{
private.GET("/data", func(c *gin.Context) {
subject := c.GetString("subject") // User UUID
siteID := c.GetString("site_id") // Site UUID
// Business logic here
})
}If you need to validate a token in an external service, use the internal/security/jwt package:
import platjwt "github.com/humanjuan/golyn/internal/security/jwt"
claims, err := platjwt.ValidateRefreshToken(tokenString)
if err == nil {
// Identity is now trusted
fmt.Printf("Subject: %s, Site: %s", claims.Subject, claims.SiteID)
}This example shows how to interact with the Golyn Backend-owned session system from a TypeScript frontend. Since tokens are stored in secure cookies, the frontend doesn't need to manage JWTs in local storage.
/**
* Golyn Authentication Service
* Handles login, authenticated requests, and automatic token refresh.
*/
interface APIResponse<T> {
success: boolean;
message?: string;
data?: T;
error?: string;
}
interface UserDTO {
id: string;
username: string;
role: string;
status: string;
site_id: string;
theme?: any;
permissions?: any;
}
interface LoginResponse {
message: string;
user: UserDTO;
provider?: string;
}
class GolynAuthService {
private static API_BASE = "https://your-golyn-domain.com/api/v1";
/**
* Login to Golyn.
* The server will set 'access_token' and 'refreshToken' HttpOnly cookies automatically.
*/
static async login(username: string, password: string): Promise<UserDTO> {
const response = await fetch(`${this.API_BASE}/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
// Important: Allow the browser to receive and store secure cookies
credentials: 'include'
});
const result: APIResponse<LoginResponse> = await response.json();
if (!result.success) {
throw new Error(result.message || "Login failed");
}
return result.data!.user;
}
/**
* Refreshes the tokens using the Refresh Token stored in the cookie.
* The server will rotate both cookies automatically.
*/
static async refreshToken(): Promise<void> {
const response = await fetch(`${this.API_BASE}/refresh_token`, {
method: 'POST',
credentials: 'include', // Crucial to send the refreshToken cookie
});
if (response.status !== 204) {
throw new Error("Session expired. Please login again.");
}
}
/**
* Fetches a fresh CSRF token. Required for POST, PUT, DELETE.
*/
static async getCSRFToken(): Promise<string> {
const response = await fetch(`${this.API_BASE}/csrf-token`, { credentials: 'include' });
const result = await response.json();
return result.csrf_token;
}
/**
* Wrapper for authenticated fetch requests.
* Automatically handles 401 Unauthorized by attempting to refresh the session.
*/
static async authenticatedFetch(url: string, options: RequestInit = {}): Promise<Response> {
const fetchOptions = {
...options,
credentials: 'include' as RequestCredentials
};
let response = await fetch(url, fetchOptions);
// If 401, the session might have expired. Try to refresh.
if (response.status === 401) {
try {
await this.refreshToken();
// Retry the original request
response = await fetch(url, fetchOptions);
} catch (err) {
throw new Error("Session expired");
}
}
return response;
}
/**
* Logout. Clears session on server and removes cookies.
*/
static async logout(): Promise<void> {
await fetch(`${this.API_BASE}/logout`, {
method: 'POST',
credentials: 'include',
});
}
}
// Usage Example:
// const user = await GolynAuthService.login("admin", "password");
// const csrf = await GolynAuthService.getCSRFToken();
// await GolynAuthService.authenticatedFetch("/api/v1/send-mail", {
// method: 'POST',
// headers: { 'X-CSRF-Token': csrf },
// body: formData
// });For local development, Golyn provides a set of scripts to manage the infrastructure and multi-site data without manually writing SQL.
Located in docker/postgresql/, this script handles the Docker container lifecycle.
./manage_db.sh start: Launches the PostgreSQL container../manage_db.sh stop: Stops the container../manage_db.sh logs: Follows the database logs../manage_db.sh cli-golyn: Opens an interactivepsqlshell directly in thegolyndatabase../manage_db.sh clean: Warning: Deletes the container and all persistent data.
This tool manages tenants (sites) and users. You can also access it via ./manage_db.sh clients.
./manage_db.sh clients list: Shows all registered sites and users../manage_db.sh clients add-site <key> <host>: Registers a new site (e.g.,hr-site hr.local)../manage_db.sh clients add-user <site_key> <username> <password>: Creates a user for a specific site.- Automatic Hashing: The script automatically detects if the password is plain text and hashes it using the Golyn binary before storing it in the database.
To improve maintainability, Golyn uses a centralized query map in database/queries.go. This allows all SQL statements to be audited and optimized in one place, avoiding hardcoded SQL in data repositories.
Note on Docker: The provided Docker configurations are intended for development only. Choosing the final production database (PostgreSQL, RDS, etc.) and the orchestration layer (Docker, Kubernetes, or bare metal) is the responsibility of the implementer. Golyn is designed to be infrastructure-agnostic.
The server is developed in Golang and, as part of its architecture, uses the following components:
- Gin framework: A high-performance HTTP web framework designed for building modular and fast applications.
- Logger: A custom logging library developed for advanced and highly configurable logging capabilities.
- AES-GCM Encryption: For sensitive configuration data
- Custom Middleware Stack: For security, compression, and routing
The Golyn Server operates as a centralized, multi-site server. Each site's settings are configured separately using .conf files, which are loaded dynamically at runtime.
- config: Configuration files for sites and the server.
- cmd: Core executable to start the Golyn server.
- internal: Internal packages, handlers, and utilities.
- middlewares: Gin middlewares for security and auth.
- modules: Feature-specific modules (auth, admin, user).
- routes: API route definitions.
- app: Core logic and shared application components.
- sites: Contains the sites that will be served by the server.
- var: Server and database log files.
- builds: Build scripts to package the server for multiple platforms.
- Each site has its own
.conffile, located in theconfig/sitesdirectory. - These files define:
- Domain mappings (e.g.,
golyn.local,humanjuan.com). - Static file paths for assets, JavaScript and styles.
- Security settings like allowed origins, HTTPS enforcement, and Custom Content Security Policy.
- SMTP configuration for emails.
- Reverse proxy settings.
- Domain mappings (e.g.,
[settings]
enabled = true
directory = portfolio
domains = humanjuan.com, humanjuan.local
# Security settings
allow_origin = https://humanjuan.com, https://humanjuan.local
enable_https_redirect = true
# Optional: Override default CSP
content_security_policy = default-src 'self'; img-src 'self' data:;
# Mail SMTP settings
smtp_host=mail.example.com
smtp_port=587
smtp_user=user@example.com
smtp_password=${SMTP_PASS}-
Personal Portfolio Hosting:
Showcase your work and skills in a polished, professional way. -
Multi-Site Management:
Create, configure, and host multiple websites on a single server. -
Extendability for Future Use Cases:
The server's modular architecture allows it to adapt to future needs, such as integrating APIs, authentication systems, or more. -
Identity as a Service (IDaaS): Use Golyn as a centralized authentication hub for all your projects. It provides:
- Single Sign-On (SSO): One login for multiple subdomains or services.
- Multi-tenancy: Isolated user management per site/tenant.
- Token Federation: Standardized JWTs that can be validated by any backend (Go, Node.js, Python, etc.).
- Programming Language: Golang
- Configuration Management: Custom
.conffiles loaded dynamically. - Logging Library: Integrated logging for server and database activities.
- Static Assets: Hosted via site-specific directories.
- Database Connectivity: Integrated PostgreSQL support using high-performance connection pooling and secure SSL/TLS connections.
- TLS/SSL Support: Security-first approach with A+ grade HTTPS encryption, supporting full certificate chains and per-site configuration.
To start the Golyn Server:
- Clone or download this repository onto your local machine.
- Navigate to the project root directory.
- Run the following command:
go run cmd/golyn.goThis will initialize the server using the configurations set in config/server/web_server.conf and site-specific .conf files located in config/sites/.
- Server Configuration:
Modifyconfig/server/web_server.conffor global settings like ports, timeouts, caching, sites conf and logging.
- Each site has its own
.conffile in theconfig/sites/directory. - These files define:
enabled: Whether the site is active (true/false).directory: Directory for the site (e.g.,golyn).domains: Domain mappings (e.g.,golyn.humanjuan.com, golyn.humanjuan.local).static_files_path,js_path,style_path: Paths to static assets, JavaScript, and styles.cert_path,key_path,chain_path: Paths to TLS/SSL certificates.allow_origin: CORS policies.enable_https_redirect: Redirect HTTP to HTTPS (true/false).proxy,proxy_target: Reverse proxy settings (e.g.,proxy=true,proxy_target=http://backend:8080).smtp_host,smtp_port,smtp_user,smtp_password: SMTP settings for email functionality.smtp_passwordcorresponds to the environment variable configured with the appropriate format (e.g.,${SMTP_PORTFOLIO_PASS}
Golyn allows you to configure SMTP credentials securely using AES-256 encryption, protecting sensitive passwords without storing them in plain text. The process below explains how to encrypt, declare, and use an SMTP password for a specific site.
Use the following command to encrypt your SMTP password using the server’s private key:
go run cmd/golyn.go --encrypt <password> --site <site_name><password>: Your plain text SMTP password.<site_name>: The name of the site this password will be used for (e.g., portfolio).
This will output a line like: SMTP_PORTFOLIO_PASS=ENC:AES256:2fa8bd3dd10f9e3022c3f739...
Copy the entire generated line (including ENC:AES256:) and declare it as an environment variable:
export SMTP_PORTFOLIO_PASS=ENC:AES256:2fa8bd3dd10f9e3022c3f739...You can place this in .bashrc, .env, a systemd unit, or any environment configuration method you use.
In the site’s configuration file config/sites/<site>.conf, use the environment variable in smtp_password as follows:
smtp_host=smtp.example.com
smtp_port=587
smtp_user=example@golyn.com
smtp_password=${SMTP_PORTFOLIO_PASS}
smtp_rate_limit_requests=2
Contributions are welcome! If you'd like to suggest a feature, fix a bug, or improve code/documentation, feel free to open an issue or submit a pull request.
For any questions, suggestions or collaboration requests, feel free to contact me!
