Files
ackify-ce/README_FR.md
2025-10-08 15:28:55 +02:00

15 KiB
Raw Permalink Blame History

🔐 Ackify

Proof of Read. Compliance made simple.

Service sécurisé de validation de lecture avec traçabilité cryptographique et preuves incontestables.

Build Security Go License

🌍 English version available here

Visitez notre site : https://www.ackify.eu/fr

🎯 Pourquoi Ackify ?

Problème : Comment prouver qu'un collaborateur a bien lu et compris un document important ?

Solution : Signatures cryptographiques Ed25519 avec horodatage immutable et traçabilité complète.

Cas d'usage concrets

  • Validation de politiques de sécurité
  • Attestations de formation obligatoire
  • Prise de connaissance RGPD
  • Accusés de réception contractuels
  • Procédures qualité et compliance

📸 Vidéos

Cliquez sur les GIFs pour ouvrir les vidéos WebM dans votre navigateur.

1) Création dune signature
Initialisation d’une signature
2) Parcours de signature utilisateur
Parcours de signature utilisateur

📸 Captures d'écran

Page d'accueil
Page d'accueil
Demande de signature
Demande de signature
Signature confirmée
Signature confirmée
Liste des signatures
Liste des signatures
Intégration Outline
Intégration Outline
Intégration Google Docs
Intégration Google Docs

Démarrage Rapide

Avec Docker (recommandé)

# Installation automatique
curl -fsSL https://raw.githubusercontent.com/btouchard/ackify/main/install/install.sh | bash

# Ou téléchargement manuel
curl -O https://raw.githubusercontent.com/btouchard/ackify/main/install/compose.yml
curl -O https://raw.githubusercontent.com/btouchard/ackify/main/install/.env.example

# Configuration
cp .env.example .env
# Éditez .env avec vos paramètres OAuth2

# Génération des secrets
export ACKIFY_OAUTH_COOKIE_SECRET=$(openssl rand -base64 32)
export ACKIFY_ED25519_PRIVATE_KEY=$(openssl rand 64 | base64 -w 0)

# Démarrage
docker compose up -d

# Test
curl http://localhost:8080/health

Variables obligatoires

ACKIFY_BASE_URL="https://votre-domaine.com"
ACKIFY_OAUTH_CLIENT_ID="your-oauth-client-id"        # Google/GitHub/GitLab
ACKIFY_OAUTH_CLIENT_SECRET="your-oauth-client-secret"
ACKIFY_DB_DSN="postgres://user:password@localhost/ackify?sslmode=disable"
ACKIFY_OAUTH_COOKIE_SECRET="$(openssl rand -base64 32)"

Optionnel : Notifications email (SMTP)

ACKIFY_MAIL_HOST="smtp.gmail.com"              # Serveur SMTP
ACKIFY_MAIL_PORT="587"                         # Port SMTP (défaut: 587)
ACKIFY_MAIL_USERNAME="votre-email@gmail.com"   # Identifiant SMTP
ACKIFY_MAIL_PASSWORD="votre-app-password"      # Mot de passe SMTP
ACKIFY_MAIL_FROM="noreply@entreprise.com"      # Adresse expéditeur
ACKIFY_MAIL_FROM_NAME="Ackify"                 # Nom expéditeur
# Si ACKIFY_MAIL_HOST n'est pas défini, le service email est désactivé (pas d'erreur)

🚀 Utilisation Simple

1. Demander une signature

https://votre-domaine.com/sign?doc=procedure_securite_2025

→ L'utilisateur s'authentifie via OAuth2 et valide sa lecture

2. Vérifier les signatures

# API JSON - Liste complète
curl "https://votre-domaine.com/status?doc=procedure_securite_2025"

# Badge PNG - Statut individuel  
curl "https://votre-domaine.com/status.png?doc=procedure_securite_2025&user=jean.dupont@entreprise.com"

3. Intégrer dans vos pages

<!-- Widget intégrable -->
<iframe src="https://votre-domaine.com/embed?doc=procedure_securite_2025" 
        width="500" height="300"></iframe>

<!-- Via oEmbed -->
<script>
fetch('/oembed?url=https://votre-domaine.com/embed?doc=procedure_securite_2025')
  .then(r => r.json())
  .then(data => document.getElementById('signatures').innerHTML = data.html);
</script>

🔧 Configuration OAuth2

Providers supportés

Provider Configuration
Google ACKIFY_OAUTH_PROVIDER=google
GitHub ACKIFY_OAUTH_PROVIDER=github
GitLab ACKIFY_OAUTH_PROVIDER=gitlab + ACKIFY_OAUTH_GITLAB_URL
Custom Endpoints personnalisés

Provider personnalisé

# Laissez ACKIFY_OAUTH_PROVIDER vide
ACKIFY_OAUTH_AUTH_URL="https://auth.company.com/oauth/authorize"
ACKIFY_OAUTH_TOKEN_URL="https://auth.company.com/oauth/token"
ACKIFY_OAUTH_USERINFO_URL="https://auth.company.com/api/user"
ACKIFY_OAUTH_SCOPES="read:user,user:email"

Restriction par domaine

ACKIFY_OAUTH_ALLOWED_DOMAIN="@entreprise.com"  # Seuls les emails @entreprise.com

Log level setup

ACKIFY_LOG_LEVEL="info" # can be debug, info, warn(ing), error. default: info

🛡️ Sécurité & Architecture

Sécurité cryptographique

  • Ed25519 : Signatures numériques de pointe
  • SHA-256 : Hachage des payloads contre le tampering
  • Horodatage immutable : Triggers PostgreSQL
  • Sessions chiffrées : Cookies sécurisés
  • CSP headers : Protection XSS

Architecture Go

cmd/ackapp/              # Point d'entrée
internal/
  domain/                # Logique métier
    models/              # Entités
    repositories/        # Interfaces persistance
  application/           # Use cases  
    services/            # Implémentations métier
  infrastructure/        # Adaptateurs
    auth/               # OAuth2
    database/           # PostgreSQL
    email/              # Service SMTP
    config/             # Configuration
  presentation/          # HTTP
    handlers/           # Contrôleurs + interfaces
    templates/          # Vues HTML
pkg/                    # Utilitaires partagés

Stack technique

  • Go 1.24.5 : Performance et simplicité
  • PostgreSQL : Contraintes d'intégrité
  • OAuth2 : Multi-providers
  • SMTP : Rappels de signature par email (optionnel)
  • Docker : Déploiement simplifié
  • Traefik : Reverse proxy HTTPS

📊 Base de Données

-- Table principale des signatures
CREATE TABLE signatures (
    id BIGSERIAL PRIMARY KEY,
    doc_id TEXT NOT NULL,                    -- ID document
    user_sub TEXT NOT NULL,                  -- ID OAuth utilisateur
    user_email TEXT NOT NULL,                -- Email utilisateur
    signed_at TIMESTAMPTZ NOT NULL,          -- Timestamp signature
    payload_hash TEXT NOT NULL,              -- Hash cryptographique
    signature TEXT NOT NULL,                 -- Signature Ed25519
    nonce TEXT NOT NULL,                     -- Anti-replay
    created_at TIMESTAMPTZ DEFAULT now(),    -- Immutable
    referer TEXT,                            -- Source (optionnel)
    prev_hash TEXT,                          -- Prev Hash
    UNIQUE (doc_id, user_sub)                -- Une signature par user/doc
);

-- Table des signataires attendus (pour le suivi)
CREATE TABLE expected_signers (
    id BIGSERIAL PRIMARY KEY,
    doc_id TEXT NOT NULL,
    email TEXT NOT NULL,
    name TEXT NOT NULL DEFAULT '',           -- Nom d'affichage (optionnel)
    added_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    added_by TEXT NOT NULL,                  -- Admin qui a ajouté
    notes TEXT,
    UNIQUE (doc_id, email)                   -- Une attente par email/doc
);

-- Table des métadonnées de documents
CREATE TABLE documents (
    doc_id TEXT PRIMARY KEY,
    title TEXT NOT NULL DEFAULT '',
    url TEXT NOT NULL DEFAULT '',            -- Emplacement du document
    checksum TEXT NOT NULL DEFAULT '',       -- SHA-256/SHA-512/MD5
    checksum_algorithm TEXT NOT NULL DEFAULT 'SHA-256',
    description TEXT NOT NULL DEFAULT '',
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    created_by TEXT NOT NULL DEFAULT ''
);

Garanties :

  • Unicité : Un utilisateur = une signature par document
  • Immutabilité : created_at protégé par trigger
  • Intégrité : Hachage SHA-256 pour détecter modifications
  • Non-répudiation : Signature Ed25519 cryptographiquement prouvable
  • Suivi : Signataires attendus pour monitoring de complétion
  • Métadonnées : Informations de documents avec URL, checksum et description

🚀 Déploiement Production

compose.yml

version: '3.8'
services:
  ackapp:
    image: btouchard/ackify-ce:latest
    environment:
      ACKIFY_BASE_URL: https://ackify.company.com
      ACKIFY_DB_DSN: postgres://user:pass@postgres:5432/ackdb?sslmode=require
      ACKIFY_OAUTH_CLIENT_ID: ${ACKIFY_OAUTH_CLIENT_ID}
      ACKIFY_OAUTH_CLIENT_SECRET: ${ACKIFY_OAUTH_CLIENT_SECRET}
      ACKIFY_OAUTH_COOKIE_SECRET: ${ACKIFY_OAUTH_COOKIE_SECRET}
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ackify.rule=Host(`ackify.company.com`)"
      - "traefik.http.routers.ackify.tls.certresolver=letsencrypt"

  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: ackdb
      POSTGRES_USER: ackuser
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data

Variables production

# Sécurité renforcée
ACKIFY_OAUTH_COOKIE_SECRET="$(openssl rand 64 | base64 -w 0)"
ACKIFY_ED25519_PRIVATE_KEY="$(openssl rand 64 | base64 -w 0)"

# HTTPS obligatoire
ACKIFY_BASE_URL="https://ackify.company.com"

# PostgreSQL sécurisé
ACKIFY_DB_DSN="postgres://user:pass@postgres:5432/ackdb?sslmode=require"

# Optionnel : SMTP pour rappels de signature
ACKIFY_MAIL_HOST="smtp.entreprise.com"
ACKIFY_MAIL_FROM="noreply@entreprise.com"
ACKIFY_MAIL_USERNAME="${SMTP_USERNAME}"
ACKIFY_MAIL_PASSWORD="${SMTP_PASSWORD}"

📋 API Complète

Authentification

  • GET /login?next=<url> - Connexion OAuth2
  • GET /logout - Déconnexion
  • GET /oauth2/callback - Callback OAuth2

Signatures

  • GET /sign?doc=<id> - Interface de signature
  • POST /sign - Créer signature
  • GET /signatures - Mes signatures (auth requis)

Consultation

  • GET /status?doc=<id> - JSON toutes signatures
  • GET /status.png?doc=<id>&user=<email> - Badge PNG

Intégration

  • GET /oembed?url=<embed_url> - Métadonnées oEmbed
  • GET /embed?doc=<id> - Widget HTML

Supervision

  • GET /health - Health check

Administration

  • GET /admin - Tableau de bord (restreint)
  • GET /admin/docs/{docID} - Détails du document avec gestion des signataires attendus
  • POST /admin/docs/{docID}/expected - Ajouter des signataires attendus
  • POST /admin/docs/{docID}/expected/remove - Retirer un signataire attendu
  • POST /admin/docs/{docID}/reminders/send - Envoyer des rappels par email aux lecteurs en attente
  • GET /admin/docs/{docID}/reminders/history - Obtenir l'historique des rappels en JSON
  • GET /admin/docs/{docID}/metadata - Obtenir les métadonnées du document en JSON
  • POST /admin/docs/{docID}/metadata - Créer ou mettre à jour les métadonnées du document
  • DELETE /admin/docs/{docID}/metadata - Supprimer les métadonnées du document
  • GET /admin/docs/{docID}/status.json - Statut du document en JSON (AJAX)
  • GET /admin/api/chain-integrity/{docID} - Vérification d'intégrité de chaîne (JSON)

Contrôle d'accès: définir ACKIFY_ADMIN_EMAILS avec des emails admins, séparés par des virgules (correspondance exacte, insensible à la casse). Exemple:

ACKIFY_ADMIN_EMAILS="alice@entreprise.com,bob@entreprise.com"

Gestion des Métadonnées de Documents

Les administrateurs peuvent gérer des métadonnées complètes pour chaque document :

  • Stocker les informations : Titre, URL/emplacement, checksum, description
  • Vérification d'intégrité : Support pour les checksums SHA-256, SHA-512 et MD5
  • Accès facile : Copie en un clic pour les checksums, URLs de documents cliquables
  • Horodatage automatique : Suivi de la création et des mises à jour avec triggers PostgreSQL
  • Intégration email : URL du document automatiquement incluse dans les emails de rappel

Fonctionnalité Signataires Attendus

Les administrateurs peuvent définir et suivre les signataires attendus pour chaque document :

  • Ajouter des signataires : Coller des emails séparés par des sauts de ligne, virgules ou point-virgules
  • Support des noms : Utiliser le format "Nom email@example.com" pour les emails personnalisés
  • Suivre la complétion : Barre de progression visuelle avec pourcentage
  • Monitorer le statut : Voir qui a signé (✓) vs. qui est en attente ()
  • Rappels par email : Envoyer des rappels en masse ou sélectifs dans la langue de l'utilisateur
  • Détecter les signatures inattendues : Identifier les utilisateurs qui ont signé sans être attendus
  • Partage facile : Copie en un clic du lien de signature du document
  • Gestion en masse : Ajouter/retirer des signataires individuellement ou en lot

🔍 Développement & Tests

Build local

# Dépendances
go mod tidy

# Build
go build ./cmd/community

# Linting
go fmt ./...
go vet ./...

# Tests (TODO: ajouter des tests)
go test -v ./...

Docker development

# Build image
docker build -t ackify-ce:dev .

# Run avec base locale
docker run -p 8080:8080 --env-file .env ackify:dev

🤝 Support

Aide & Documentation

Licence AGPLv3

Distribué sous la licence GNU Affero General Public License v3.0. Voir LICENSE pour plus de détails.


Développé avec ❤️ par Benjamin TOUCHARD