Benjamin a46715a2f3 fix: robust coverage calculation in test suite script
Fix bash arithmetic syntax error when calculating coverage percentages
from LCOV files. The issue occurred when grep results contained whitespace
or when values were empty strings.
2025-11-24 00:23:56 +01:00
2025-11-07 12:08:34 +01:00

🔐 Ackify

Proof of Read. Compliance made simple.

Secure document reading validation with cryptographic signatures and irrefutable proof.

Build codecov Security Go License

🇫🇷 Version française disponible ici

Website: https://www.ackify.eu


🎯 Why Ackify?

Prove that collaborators have read and acknowledged important documents with Ed25519 cryptographic signatures.

Use Cases:

  • Security policy validation
  • Training attestations
  • GDPR acknowledgment
  • Contractual agreements
  • Compliance procedures

Key Features:

  • Ed25519 cryptographic signatures
  • Flexible authentication: OAuth2 (Google, GitHub, GitLab, custom) or MagicLink (passwordless email)
  • One signature per user/document (database enforced)
  • Immutable audit trail
  • Expected signers tracking with email reminders
  • Document checksum verification (SHA-256/512, MD5)
  • Public embeddable widgets (Notion, Outline, etc.)
  • Admin dashboard (Vue.js 3 + dark mode)
  • Multilingual (fr, en, es, de, it)

Quick Start

Prerequisites

  • Docker & Docker Compose
  • At least ONE authentication method:
    • OAuth2 credentials (Google, GitHub, or GitLab), OR
    • SMTP server for MagicLink (passwordless email authentication)

Installation

# Download and run installation script
curl -fsSL https://raw.githubusercontent.com/btouchard/ackify-ce/main/install/install.sh | bash

# Navigate to installation directory
cd ackify-ce

# Edit configuration with your OAuth2 credentials
nano .env

# Start services
docker compose up -d

# Access web interface
open http://localhost:8080

What the script does:

  • Downloads compose.yml and .env.example
  • Generates secure secrets automatically:
    • ACKIFY_OAUTH_COOKIE_SECRET (AES-256 session encryption)
    • POSTGRES_PASSWORD (database password)
  • Creates ready-to-use .env file
  • You only need to add your OAuth2 credentials

Option 2: Manual Installation

# Clone repository
git clone https://github.com/btouchard/ackify-ce.git
cd ackify-ce

# Configure
cp .env.example .env
nano .env  # Edit with your OAuth2 credentials and generate secrets

# Start services
docker compose up -d

# Verify
curl http://localhost:8080/api/v1/health
# Expected: {"status":"healthy","database":"connected"}

# Access web interface
open http://localhost:8080

Required Environment Variables

# Application
APP_DNS=sign.your-domain.com
ACKIFY_BASE_URL=https://sign.your-domain.com
ACKIFY_ORGANISATION="Your Organization"

# Database
POSTGRES_USER=ackifyr
POSTGRES_PASSWORD=your_secure_password
POSTGRES_DB=ackify

# Security (generate with: openssl rand -base64 32)
ACKIFY_OAUTH_COOKIE_SECRET=your_base64_secret

# ============================================================================
# Authentication (choose AT LEAST ONE method)
# ============================================================================

# Option 1: OAuth2 (Google, GitHub, GitLab, custom)
ACKIFY_OAUTH_PROVIDER=google
ACKIFY_OAUTH_CLIENT_ID=your_client_id
ACKIFY_OAUTH_CLIENT_SECRET=your_client_secret

# Option 2: MagicLink (passwordless email authentication)
# ACKIFY_MAIL_HOST=smtp.example.com
# ACKIFY_MAIL_PORT=587
# ACKIFY_MAIL_USERNAME=your_smtp_username
# ACKIFY_MAIL_PASSWORD=your_smtp_password
# ACKIFY_MAIL_FROM=noreply@example.com

Auto-detection:

  • OAuth is enabled automatically if ACKIFY_OAUTH_CLIENT_ID and ACKIFY_OAUTH_CLIENT_SECRET are set
  • MagicLink is enabled automatically if ACKIFY_MAIL_HOST is configured
  • You can use both methods simultaneously for maximum flexibility

See docs/en/configuration.md for all options.


📸 Screenshots

Home
Signing
Confirmed
Confirmations
Admin dashboard
Admin document
Outline

📚 Documentation

Getting Started

Features

Technical


🚀 Usage

Request a Signature

https://your-domain.com/?doc=security_policy_2025

User authenticates (OAuth2 or MagicLink) and signs with one click.

Embed in Your Tools

iFrame:

<iframe src="https://your-domain.com/embed?doc=policy_2025"
        width="600" height="200" frameborder="0"></iframe>

oEmbed (Notion, Outline, Confluence):

Paste the embed URL: https://your-domain.com/embed?doc=policy_2025
Automatic embed via oEmbed discovery

Open Graph (Slack, Teams):

Paste direct URL: https://your-domain.com/?doc=policy_2025
URL unfurls automatically with signature count

Important

: Use /embed?doc=... for iframe integrations (Notion, Outline) and /?doc=... for direct links (emails, Slack).

See docs/en/features/embedding.md for details.


🛡️ Security

  • Ed25519 - State-of-the-art elliptic curve signatures
  • SHA-256 - Payload hashing for tampering detection
  • PKCE - OAuth2 security (automatic)
  • AES-256-GCM - Encrypted refresh tokens
  • Immutable timestamps - PostgreSQL triggers
  • Rate limiting - 5 auth/min, 100 req/min
  • HTTPS enforced - Secure cookies only

See docs/en/architecture.md for full security details.


🔧 Tech Stack

Backend: Go 1.24.5, PostgreSQL 16, Chi Router, OAuth2, Ed25519

Frontend: Vue 3, TypeScript, Vite, Pinia, Tailwind CSS, shadcn/vue

DevOps: Docker, Multi-stage builds, Distroless image (< 30MB)

i18n: 5 languages (fr, en, es, de, it)

Coverage: 72.6% (180+ unit tests, 33 integration tests)


🤝 Support


📄 License

AGPLv3 - See LICENSE for details.


Developed with ❤️ by Benjamin TOUCHARD

Description
Proof of Read. Compliance made simple.
Readme AGPL-3.0 21 MiB
Languages
Go 67.6%
Vue 14.3%
TypeScript 10.8%
Shell 2.4%
PLpgSQL 2%
Other 2.9%