Digital Signature for Filament GitHub

#Model Setup

Any Eloquent model that needs to be signed must do two things:

  1. Implement the Signable contract
  2. Use the HasSignatures trait

#Implementing Signable

PHP
use Kukux\DigitalSignature\Contracts\Signable;
use Kukux\DigitalSignature\Traits\HasSignatures;

class Contract extends Model implements Signable
{
    use HasSignatures;

    // Display name shown in the signing UI
    public function getSignableTitle(): string
    {
        return $this->title;
    }

    // Path to the PDF on the configured storage disk
    public function getSignablePdfPath(): string
    {
        return $this->pdf_path;
    }

    // Primary key — used to link signatures back to this record
    public function getSignableId(): int|string
    {
        return $this->id;
    }
}

#HasSignatures trait methods

MethodReturnsDescription
signatures()MorphManyAll signature records attached to this model
pendingSignatures()MorphManyOnly signatures with status = pending
latestSignature()?SignatureThe most recently created signature, or null
isSigned()booltrue if at least one signed signature exists

#Examples

PHP
$contract = Contract::find(1);

// Check if a document has been fully signed
if ($contract->isSigned()) {
    // ...
}

// Get the most recent signature
$sig = $contract->latestSignature();
echo $sig->status;          // pending | signed | revoked | failed
echo $sig->signed_at;       // Carbon timestamp
echo $sig->uuid;            // unique token per signing request

// Loop over all signatures
foreach ($contract->signatures as $sig) {
    echo $sig->user->name . ' — ' . $sig->status;
}

// Query only pending signatures
$contract->pendingSignatures()->each(function ($sig) {
    // remind the signer
});

#Signature model attributes

AttributeTypeDescription
uuidstringUnique token per signing request
user_idintThe signer
statusstringpending, signed, revoked, failed
sourcestringdraw or upload
image_pathstringPath to the raw signature image on disk
image_hashstringSHA-256 of the image bytes
document_hashstringSHA-256 of the source PDF before signing
signed_document_pathstringPath to the completed signed PDF
signed_document_hashstringSHA-256 of the signed PDF
certificate_fingerprintstringSHA-256 fingerprint of the signer's certificate
signed_atCarbonWhen signing completed
revoked_atCarbonWhen the signature was revoked

#Multiple signable models

The trait is polymorphic — you can apply it to as many models as needed.

PHP
class Invoice extends Model implements Signable { use HasSignatures; ... }
class NdaAgreement extends Model implements Signable { use HasSignatures; ... }
class LeaveRequest extends Model implements Signable { use HasSignatures; ... }

Each model has its own signatures() relationship scoped by signable_type and signable_id.