Skip to content

Security

Security architecture and best practices for GSign.

Security Layers

┌─────────────────────────────────────────┐
│           Client (Browser)              │
│  • HTTPS only                           │
│  • CSP headers                          │
│  • XSS protection                       │
└─────────────────┬───────────────────────┘

┌─────────────────▼───────────────────────┐
│              NGINX                       │
│  • SSL/TLS termination                  │
│  • Rate limiting                        │
│  • Security headers                     │
└─────────────────┬───────────────────────┘

┌─────────────────▼───────────────────────┐
│           API Gateway                    │
│  • JWT validation                       │
│  • API key authentication               │
│  • Request validation                   │
│  • Audit logging                        │
└─────────────────┬───────────────────────┘

┌─────────────────▼───────────────────────┐
│           Service Layer                  │
│  • Authorization (RBAC)                 │
│  • Input sanitization                   │
│  • Business logic validation            │
└─────────────────┬───────────────────────┘

┌─────────────────▼───────────────────────┐
│            Data Layer                    │
│  • Encrypted at rest                    │
│  • Parameterized queries                │
│  • Tenant isolation                     │
└─────────────────────────────────────────┘

Authentication

JWT Tokens

go
// Token structure
type Claims struct {
    UserID         string `json:"user_id"`
    OrganizationID string `json:"org_id"`
    Role           string `json:"role"`
    jwt.RegisteredClaims
}

// Token settings
Access Token:  15 minutes
Refresh Token: 7 days
Algorithm:     HS256 or RS256

Password Security

SettingValue
Algorithmbcrypt
Cost Factor12
Min Length8 characters
RequirementsUpper, lower, number, special

API Keys

go
// API key format
gsign_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
gsign_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

// Storage
Hashed with SHA-256, stored in database

Authorization (RBAC)

Roles

RolePermissions
Super AdminAll platform operations
Org AdminOrganization settings, users, billing
Team AdminTeam settings, documents
UserOwn documents, sign
API UserAPI access only

Permission Checks

go
// Middleware example
func RequireRole(roles ...string) fiber.Handler {
    return func(c *fiber.Ctx) error {
        user := c.Locals("user").(User)
        for _, role := range roles {
            if user.Role == role {
                return c.Next()
            }
        }
        return c.Status(403).JSON(...)
    }
}

Data Protection

Encryption at Rest

Data TypeEncryption
Documents (S3)AES-256-GCM
Database fieldsAES-256-GCM
CertificatesPKCS#12 + password
BackupsGPG encryption

Encryption in Transit

  • TLS 1.2+ required
  • Strong cipher suites
  • HSTS enabled
  • Certificate pinning (mobile)

Security Headers

nginx
# NGINX configuration
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'" always;
add_header Permissions-Policy "geolocation=(), microphone=()" always;

Input Validation

API Validation

go
type CreateDocumentRequest struct {
    Name string `json:"name" validate:"required,min=1,max=255"`
    Tags []string `json:"tags" validate:"max=10,dive,max=50"`
}

func (h *Handler) CreateDocument(c *fiber.Ctx) error {
    var req CreateDocumentRequest
    if err := c.BodyParser(&req); err != nil {
        return c.Status(400).JSON(...)
    }
    if err := h.validator.Struct(req); err != nil {
        return c.Status(422).JSON(...)
    }
    // ...
}

File Upload Validation

CheckImplementation
File typeMagic bytes + extension
File sizeMax 25MB
Malware scanClamAV integration
PDF validationpdfcpu validation

Rate Limiting

go
// Fiber rate limiter
limiter.New(limiter.Config{
    Max:        100,           // requests
    Expiration: time.Hour,     // per hour
    KeyGenerator: func(c *fiber.Ctx) string {
        return c.IP()
    },
})
ResourceLimit
IP address100/hour
API key (free)100/hour
API key (paid)1,000/hour
Login attempts5/15min

Audit Trail

Logged Events

  • User login/logout
  • Document upload/download
  • Envelope creation/signing
  • Certificate operations
  • Admin actions
  • API access

Audit Record

go
type AuditEvent struct {
    UserID       string    `bson:"user_id"`
    Action       string    `bson:"action"`
    ResourceType string    `bson:"resource_type"`
    ResourceID   string    `bson:"resource_id"`
    IPAddress    string    `bson:"ip_address"`
    UserAgent    string    `bson:"user_agent"`
    Timestamp    time.Time `bson:"timestamp"`
    Metadata     bson.M    `bson:"metadata"`
}

PKI Security

Certificate Storage

  • Private keys encrypted with AES-256
  • HSM backend for production
  • Key encryption key (KEK) in environment

Signing Process

  1. User selects certificate
  2. User enters PIN
  3. Request sent to HSM
  4. HSM performs signing
  5. Signed document returned
  6. Audit log recorded

Compliance

Standards

StandardStatus
eIDAS✅ Compliant
ESIGN Act✅ Compliant
UETA✅ Compliant
GDPR✅ Ready
SOC 2🔄 In Progress

Data Retention

Data TypeRetention
Documents7 years (configurable)
Audit logs7 years
Session data30 days
Deleted accounts30 days (then purged)

Security Checklist

  • [x] HTTPS only (HSTS)
  • [x] Strong password policy
  • [x] JWT with short expiry
  • [x] Rate limiting
  • [x] Input validation
  • [x] SQL injection prevention
  • [x] XSS protection
  • [x] CSRF protection
  • [x] Security headers
  • [x] Audit logging
  • [x] Encryption at rest
  • [x] Encryption in transit
  • [x] Tenant isolation
  • [ ] Penetration testing
  • [ ] Security audit
  • [ ] SOC 2 certification

GSign Digital Signature Platform