Sharokey
Service gratuit en version bêta - Profitez de toutes les fonctionnalités sans frais

Intégrer Sharokey dans Jira : Partage Sécurisé d'Identifiants

24 septembre 2025

Intégration Sharokey dans Jira

Sharokey permet de créer des liens auto-destructeurs pour partager des identifiants de manière sécurisée directement depuis vos tickets Jira. Cette solution de partage temporaire sécurisé s'intègre parfaitement dans vos workflows existants.

Fonctionnalités principales

  • Liens auto-destructeurs : Accès unique puis destruction automatique
  • Chiffrement AES-256 : Zero-knowledge, protection maximale des données
  • Accès temporaire contrôlé : Expiration automatique configurée
  • Intégration transparente : Directement dans l'interface Jira
  • Interface web : Aucune installation requise

Prérequis

Installation

Étape 1 : Installation de Tampermonkey

  1. Installez l'extension depuis le store de votre navigateur :
  2. Activez l'extension dans votre navigateur

Étape 2 : Configuration du UserScript

  1. Cliquez sur l'icône Tampermonkey puis "Créer un nouveau script"
  2. Remplacez le contenu par défaut par le script suivant :
// ==UserScript==
// @name         Jira Sharokey Integration
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Intégration Sharokey pour partage sécurisé d'identifiants
// @author       Sharokey
// @match        https://*.atlassian.net/*
// @match        https://*/jira/*
// @grant        none
// @require      https://cdn.jsdelivr.net/gh/Sharokey/sharokey-cdn@latest/sharokey.js
// ==/UserScript==

(function() {
    'use strict';
    
    // Configuration - Remplacez par votre token API Sharokey
    const SHAROKEY_TOKEN = 'sk_live_VOTRE_TOKEN_API';
    
    // Configuration Sharokey
    if (typeof Sharokey !== 'undefined') {
        Sharokey.config({token: SHAROKEY_TOKEN});
    }
    
    function getTicketInfo() {
        const ticketKey = document.querySelector('[data-testid="issue.views.issue-base.foundation.breadcrumbs.current-issue.item"]')?.textContent?.trim() 
                         || document.querySelector('#key-val')?.textContent?.trim()
                         || window.location.pathname.match(/([A-Z]+-\\\\d+)/)?.[1]
                         || 'TICKET';
        
        const ticketTitle = document.querySelector('[data-testid="issue.views.issue-base.foundation.summary.heading"]')?.textContent?.trim()
                           || document.querySelector('#summary-val')?.textContent?.trim()
                           || 'Demande support';
        
        return { key: ticketKey, title: ticketTitle };
    }
    
    function showSecretForm() {
        return new Promise((resolve, reject) => {
            const modal = document.createElement('div');
            modal.innerHTML = \`
                <div style="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:10000;display:flex;justify-content:center;align-items:center;font-family:Arial,sans-serif;">
                    <div style="background:white;padding:30px;border-radius:8px;max-width:500px;width:90%;">
                        <h2 style="margin-top:0;color:#0052CC;">Créer un accès sécurisé</h2>
                        <form id="secretForm">
                            <div style="margin-bottom:15px;">
                                <label style="display:block;margin-bottom:5px;font-weight:bold;">Contenu du secret :</label>
                                <textarea id="secretContent" required style="width:100%;height:150px;padding:8px;border:1px solid #ddd;border-radius:4px;resize:vertical;" placeholder="Entrez les identifiants, mots de passe ou informations à partager de manière sécurisée..."></textarea>
                            </div>
                            <div style="margin-bottom:20px;">
                                <label style="display:block;margin-bottom:5px;font-weight:bold;">Instructions (optionnel) :</label>
                                <input type="text" id="instructions" style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;" placeholder="Instructions d'utilisation">
                            </div>
                            <div>
                                <button type="submit" style="background:#0052CC;color:white;border:none;padding:12px 20px;border-radius:4px;cursor:pointer;margin-right:10px;">Créer le secret</button>
                                <button type="button" id="cancelBtn" style="background:#666;color:white;border:none;padding:12px 20px;border-radius:4px;cursor:pointer;">Annuler</button>
                            </div>
                        </form>
                    </div>
                </div>
            \`;
            
            document.body.appendChild(modal);
            document.getElementById('secretContent').focus();
            
            document.getElementById('secretForm').onsubmit = function(e) {
                e.preventDefault();
                const content = document.getElementById('secretContent').value.trim();
                const instructions = document.getElementById('instructions').value.trim();
                
                if (!content) {
                    alert('Le contenu du secret est obligatoire');
                    return;
                }
                
                document.body.removeChild(modal);
                resolve({ content, instructions });
            };
            
            document.getElementById('cancelBtn').onclick = function() {
                document.body.removeChild(modal);
                reject(new Error('Annulé'));
            };
        });
    }
    
    async function createSecret(ticketInfo, secretData) {
        let content = \`Ticket : \${ticketInfo.key}
Contexte : \${ticketInfo.title}

\${secretData.content}\`;
        
        if (secretData.instructions) {
            content += \`\\n\\nInstructions : \${secretData.instructions}\`;
        }
        
        const secret = await Sharokey.create(content, 24, 2, {
            description: \`Accès temporaire - \${ticketInfo.key}\`
        });
        
        return secret;
    }
    
    function showResult(shareUrl, ticketKey) {
        const modal = document.createElement('div');
        modal.innerHTML = \`
            <div style="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:10000;display:flex;justify-content:center;align-items:center;font-family:Arial,sans-serif;">
                <div style="background:white;padding:30px;border-radius:8px;max-width:500px;">
                    <h2 style="color:#0052CC;margin-top:0;">Secret créé avec succès</h2>
                    <p><strong>Ticket :</strong> \${ticketKey}</p>
                    <p><strong>Lien sécurisé :</strong></p>
                    <div style="background:#f4f5f7;padding:15px;border-radius:4px;word-break:break-all;font-family:monospace;border:1px solid #ddd;">\${shareUrl}</div>
                    <div style="margin-top:20px;">
                        <button id="copyBtn" style="background:#0052CC;color:white;border:none;padding:10px 20px;border-radius:4px;cursor:pointer;margin-right:10px;">Copier le lien</button>
                        <button id="closeBtn" style="background:#666;color:white;border:none;padding:10px 20px;border-radius:4px;cursor:pointer;">Fermer</button>
                    </div>
                    <p style="font-size:12px;color:#666;margin-top:15px;">
                        Le secret expire automatiquement<br>
                        Lien auto-destructible après consultation
                    </p>
                </div>
            </div>
        \`;
        
        document.body.appendChild(modal);
        
        document.getElementById('copyBtn').onclick = function() {
            navigator.clipboard.writeText(shareUrl).then(() => {
                this.textContent = 'Copié !';
                this.style.background = '#00C851';
                setTimeout(() => {
                    this.textContent = 'Copier le lien';
                    this.style.background = '#0052CC';
                }, 2000);
            });
        };
        
        document.getElementById('closeBtn').onclick = function() {
            document.body.removeChild(modal);
        };
    }
    
    function createSharokeyButton() {
        const ticketInfo = getTicketInfo();
        if (!ticketInfo.key || ticketInfo.key === 'TICKET' || document.getElementById('sharokey-button')) {
            return;
        }
        
        const targetElement = document.querySelector('[data-testid="issue.views.issue-base.foundation.summary.heading"]')
                             || document.querySelector('#stalker')
                             || document.querySelector('.aui-toolbar2-primary');
        
        if (!targetElement) return;
        
        const button = document.createElement('button');
        button.id = 'sharokey-button';
        button.innerHTML = '🔐 Créer un accès sécurisé';
        button.style.cssText = \`
            background:#0052CC;
            color:white;
            border:none;
            padding:8px 16px;
            border-radius:4px;
            cursor:pointer;
            font-size:14px;
            margin-left:10px;
        \`;
        
        button.onclick = async function() {
            if (SHAROKEY_TOKEN === 'sk_live_VOTRE_TOKEN_API') {
                alert('Veuillez configurer votre token API Sharokey dans le script');
                return;
            }
            
            const originalText = this.innerHTML;
            this.innerHTML = 'Création...';
            this.disabled = true;
            
            try {
                const secretData = await showSecretForm();
                const result = await createSecret(getTicketInfo(), secretData);
                showResult(result.share_url, getTicketInfo().key);
            } catch (error) {
                if (error.message !== 'Annulé') {
                    alert('Erreur : ' + error.message);
                }
            } finally {
                this.innerHTML = originalText;
                this.disabled = false;
            }
        };
        
        targetElement.appendChild(button);
    }
    
    function init() {
        setTimeout(createSharokeyButton, 2000);
        setInterval(createSharokeyButton, 5000);
    }
    
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();

Étape 3 : Configuration du token API

  1. Récupérez votre token API depuis votre compte Sharokey
  2. Remplacez sk_live_VOTRE_TOKEN_API par votre token réel
  3. Sauvegardez le script (Ctrl+S)

Utilisation

Workflow standard

  1. Ouvrez un ticket dans Jira
  2. Cliquez sur le bouton "🔐 Créer un accès sécurisé"
  3. Saisissez directement le contenu du secret (identifiants, mots de passe, etc.)
  4. Ajoutez des instructions si nécessaire
  5. Cliquez sur "Créer le secret"
  6. Copiez le lien généré et partagez-le avec le demandeur

Fonctionnalités

Personnalisation

Modifier la durée d'expiration

Dans la fonction createSecret, modifiez le paramètre hours :

const secret = await Sharokey.create(content, 48, 1, { // Durée personnalisée

Adapter à votre instance Jira

Modifiez les URLs dans l'en-tête du script pour correspondre à votre environnement :

// @match        https://votre-jira.company.com/*

Ajouter des restrictions de sécurité

const secret = await Sharokey.create(content, expiration, consultations, {
    description: `Accès temporaire - ${ticketInfo.key}`,
    captcha: true,  // Ajouter un CAPTCHA
    otpEmail: "[email protected]"  // Double authentification
});

Dépannage

Le bouton n'apparaît pas

Erreur lors de la création du secret

Compatibilité avec différentes versions de Jira

Le script utilise plusieurs sélecteurs pour s'adapter aux différentes versions de Jira. Si nécessaire, ajustez les sélecteurs CSS dans la fonction getTicketInfo().

Sécurité et bonnes pratiques

Protection du token API

Gestion des secrets

Conclusion

Cette intégration Sharokey-Jira démontre la facilité avec laquelle Sharokey peut s'intégrer dans n'importe quelle interface web existante. Le même principe peut être appliqué à ServiceNow, Zendesk, Salesforce, ou toute autre plateforme web que votre organisation utilise.

L'approche UserScript présentée ici illustre comment transformer rapidement n'importe quel workflow métier existant en ajoutant des capacités de partage sécurisé, sans modification de l'application principale.

Pour des besoins plus avancés, consultez la documentation API Sharokey qui propose des intégrations plus poussées via les SDKs Python, JavaScript et CLI.