Privacy
Last updated: 15 October 2026
Your photos are opened, watermarked, resized and packed into a ZIP by the code running in this page. They are not uploaded, not copied to a server, and not seen by us or by anyone else. There is no upload code in this site to do it with.
What happens to a photo
- You drop a file in. The browser hands the page a reference to it on your disk.
- The page reads the first part of the file to find which way up it goes.
- The browser decodes it, the page draws it onto a canvas with your watermark, and the browser re-encodes it.
- The result is put into a ZIP that is built in this page's memory.
- You download that ZIP from your own machine.
At no point is there a request carrying the picture, because the code that would make one does not exist here.
What this page loads
| What | From | Why |
|---|---|---|
| HTML, CSS, JavaScript | signetdrop.tekiba.app | The tool itself. No library is fetched from anywhere else. |
| Google Analytics | googletagmanager.com, google-analytics.com | The counters listed below, and nothing else. It never sees a file. |
| Paddle | cdn.paddle.com, and Paddle's checkout | Only after you press a buy button. It handles the payment; we never see a card number. |
| Licence service | license.tekiba.app | Two requests, described under "the paid version" below. |
| Licence service, test builds only | tekiba-license-sandbox.metluno.workers.dev | A sandbox copy of the same thing, so a purchase can be rehearsed without a real card. This site never contacts it — the address is chosen by hostname, and only a deployment preview picks the sandbox one. |
There are no fonts from another domain, no advertising, and no trackers beyond the counters named above.
What is counted
Google Analytics is switched on for this site. Ten events are sent, each with a fixed shape, listed here in full:
| Event | Carries |
|---|---|
batch_result |
how the batch ended — exactly one of ok,
too_many_files, unsupported,
error or empty — how many photos,
which output format, which band the count falls in (1, 2–10, 11–50, or 51 and over), and which
marketplace preset was last chosen, by its name (Etsy, Poshmark, Amazon, eBay, Shopify, MLS, Mercari, Yahoo! Auctions, Rakuma, real estate listings, online shop) or none |
upgrade_click | which upgrade button was pressed |
license_activated | whether a key arrived from a purchase or was pasted in |
tool_result | that a batch produced a result — only the tool's name, signetdrop |
export | that the ZIP was downloaded, the image format inside it (JPEG, PNG or WebP), and which of those bands the number of photos in it falls in — the band, not the number |
paywall_view | that the paid version's offer was on screen on the free version — at most once per visit to the page |
buy_click | that a buy button was pressed |
settings_saved | that settings were saved under a name or imported from a file (paid), and how many this browser now holds, as a band (1, 2–5, 6–10 or 11–20) — never a name or a setting |
guide_to_tool | sent from an article: which article, by its own address name, and that the link went to the tool |
plan_interest | sent from the Japanese pages under /ja/: that the monthly-plan button was pressed — only the word monthly. There is no monthly plan yet; the button says so, and counts how many people would want one |
No file name, no image size in pixels, no watermark text, no part of a picture.
No price, nothing you typed. The code that builds these is
/assets/analytics.js, with a list of the fields each event may
carry; anything else is dropped before sending. The articles add
/assets/guide.js, which sends guide_to_tool, and the
Japanese pages add /assets/ja.js, which sends plan_interest.
Google Analytics also receives what any web request carries: an IP address (which it is asked to shorten), a rough location derived from it, the page address, the referring page, and your browser's user-agent string. It sets its own cookies.
The page address is cleaned first on the page you land on after buying.
Paddle sends you back to /thanks/?txn=…, and that transaction ID
is enough on its own to fetch your licence key — so it is taken out of the address before
anything, analytics included, can read it. The code is
/assets/claimurl.js and it runs ahead of the analytics tag. That
page is also served with Referrer-Policy: no-referrer, so the
address cannot travel to the next page either.
If your browser will not let this page remember anything — a private window with site data blocked — then the address is the only thing holding your purchase, and removing it would lose you the key. In that case it is left alone and analytics does not start at all on that page. Either way the ID is not sent to Google.
EXIF, and what is removed
Photographs often carry EXIF: the camera, its serial number, the date, and sometimes the exact place the picture was taken.
By default, none of it survives. Output is drawn onto a canvas and re-encoded, and a canvas has nothing to write out about where a photo was taken or what took it. That is a consequence of how the tool works, not a filter that might miss a field.
To be exact about what the file does contain: the browser's encoder writes a few headers of its own for the new file. On Chromium that is a JFIF header and a standard sRGB colour profile of a few hundred bytes, the same block every time; other browsers may write a different header or none. They say how the pixels are stored and how the colours should be read, and identify nothing. Nothing copied from your photo that could describe you, your camera or your location is in the file. Two things outside the picture do come across: the file name, unless you choose a new one, and each file's modification date, which the ZIP records.
The paid version has an option to carry the original EXIF across. It is off unless you switch it on, and when it is on the photo's EXIF block goes across with these changes. A standard rotation tag is reset, because the picture has already been turned the right way up. The size and colour space the block states are set to match the new picture, which may be smaller and is always sRGB. And with "Strip GPS location" ticked, as it is to start with, the GPS fields are removed — the data itself, not just the pointer to it — along with the camera body and lens serial numbers and the camera owner's name, each of which can single out one camera, the small preview picture a camera embeds (it shows the photo as it was, without your watermark), every field text can be typed into — the image description, user comment, the Windows title, comment, keywords and subject fields, the document name and image title, the computer's name, the device settings description, the spectral sensitivity note, the related file format and sound file name, the image's unique ID — the camera maker's private notes and the pointer to them (MakerNote), the opaque blocks (padding, printer settings, OECF, spatial frequency response, colour filter pattern, composite exposure times, transfer function), and every byte of the block the tool has not read. Those fields are dropped whole, without reading them: deciding whether a caption names a place would sooner or later get one wrong. What stays is the date, the camera and lens settings, and the fields that name a camera, lens, program or person (make, model, software, lens model, Artist, Copyright, the Windows author), as written and not searched. A kept field in a shape it should not have — text where a number belongs, or a date that is not a date — is dropped on its own, like the free text; numbers are carried as numbers and not inspected. The exception is the rotation tag and the size and colour fields the tool corrects: if one of those is in a form it cannot rewrite in place, that photo's whole block is left out rather than carried with a value that is wrong for the new picture, and the run counts it. If a file's EXIF is laid out in a way the tool cannot fully account for, it is not carried at all rather than carried with the location in it. Untick "Strip GPS location" and the block goes across as it was apart from those corrections, GPS, serial numbers, preview, captions and anything tucked inside it included. Only the EXIF block is carried; separate XMP and IPTC blocks never are. A serial number a camera maker keeps in its own private notes is not looked for on its own: those notes go whole and unread with "Strip GPS location" ticked, and stay whole with it unticked.
If you type a name into "Copyright / artist", it replaces the Artist and Copyright fields of the EXIF being carried. Other fields that may name someone, such as the Windows author field, are left as they are; the camera owner's name stays only with "Strip GPS location" unticked. It is written as UTF-8, which current readers expect; a strict reader may show accented letters oddly. It is never added to a photo that had no EXIF of its own. Like every other setting, it stays in your browser, and goes into a preset only if you save one.
It works from a JPEG to a JPEG and nowhere else. PNG, WebP and HEIC keep metadata in their own containers, which this tool neither reads nor writes; a photo that is not a JPEG, or that you save as something else, comes out with no EXIF whichever way the option is set. The interface says so, and the result tells you how many photos in a batch were in that position.
What is stored on your machine
| Key | What | When |
|---|---|---|
tekiba.license.SIGNETDROP | Your licence key | After you buy or paste one |
tekiba.license.SIGNETDROP.revoked | Key IDs known to be cancelled | Only if a refund has been processed |
tekiba.license.SIGNETDROP.checked.… | When the key was last checked | At most monthly |
signetdrop.verify.attempted | When the refund check was last attempted | At most monthly, and only with a key |
signetdrop.key-revision | A counter that goes up when a key is added or removed, so a key you removed in one tab is not saved back by another | When you add or remove a key |
signetdrop.presets | Your saved settings (paid) | When you save a preset |
signetdrop.trial.used | How many photos this browser has put through a business preset's shape on the free version — a number, nothing about the photos | When a free batch uses the trial |
tekiba.claim.txn(session only) |
The id of the purchase whose key is being fetched | From the moment your payment completes until the key arrives |
The last one is in sessionStorage rather than
localStorage: it disappears when the tab closes. It is written the
instant the payment completes, before the page sends you on to the thank-you page, because
that step throws the checkout page away and the id would go with it. It exists so that
reloading the page after a purchase carries on fetching the same key instead of starting
over, and it is removed the moment the key arrives.
A preset holds settings only — a size, a colour, some text. It never holds a photo, a file name, or a logo image: when a preset is saved, the chosen logo's file name and the reference to it are removed first.
One item on this list does leave your machine. To find out whether a
key has been refunded, the page sends the key itself to
license.tekiba.app/verify — at most once a month, whether or
not that request succeeds, and only if you have a key. Nothing else here is ever sent
anywhere, and none of it has anything to do with your photos.
The paid version
Two things reach the network, and only these. (On a test build of this
site the licence service is a sandbox copy at
tekiba-license-sandbox.metluno.workers.dev, so that buying and
refunding can be rehearsed with Paddle's test cards. Which one is used is decided by
hostname, in one place in /assets/config.js; this site uses
the live one. Both are named in the security policy because a policy is attached to a
response rather than to a hostname.)
- Paddle handles the payment. Pressing a buy button loads Paddle's script and opens its overlay. Your card details go to Paddle and never to this page. Paddle is the seller of record; their privacy notice covers what they keep.
- The licence service at
license.tekiba.appis asked, straight after a purchase, to turn the transaction into a key (/claim?txn=…). A payment takes a few seconds to settle, so that request is repeated every two seconds for up to a minute until the key comes back, and pressing Try again starts another minute. It carries the purchase id and nothing else. The same request is made if you paste a transaction ID into the box yourself — that is how a lost key is fetched again — and it carries only the id you pasted. While a purchase is still being tracked in a tab, the page also asks once on load, so that a refund is noticed rather than waited out. A visitor who has not bought anything has no id to ask about and sends nothing. Afterwards, at most once a month, the service is asked whether that key has been refunded (/verify?key=…, which does send the key). The one exception to "once a month" is a refund we have just been told about: if the licence service reports that the purchase was refunded, the key saved here is checked immediately rather than up to thirty days later, so that this page does not go on calling itself unlocked. If it is unreachable, nothing is locked: an unlocked copy stays unlocked.
Deciding whether a key is valid does not use the network at all. The key carries a signature, and the page checks it against a public key built into the site, with the network switched off if you like. The monthly refund check described above is a separate thing: it is the only time the key leaves your browser, it is not needed for the paid version to work, and a failure to reach the service never locks anything.
How to check any of this
- Open your browser's developer tools and go to the Network tab.
- Drop in some photos and run a batch.
- No request appears carrying a photo, its name, or anything worked out from it. The only requests are this page's own files and the analytics events listed above.
The site also sends a Content-Security-Policy that the browser enforces, and it is
worth saying precisely what that buys you. Its connect-src does
not include this site, so no fetch, no XHR and no beacon from
this page can reach our server — a future mistake in our code could not post your photo
back to us, because the browser would refuse. form-action is
'none', so no form can submit anywhere.
script-src allows no inline code at all, so every script running
here is a file you can open and read.
What a policy cannot do is make leaking impossible in principle: images may be loaded
from this origin, and a request for an image can carry data in its address. What the
policy does is take away the destinations and make adding one a visible, deliberate
change to a file in the repository. The headers are in the response; the file that sets
them is _headers.
Cloudflare
The site is served by Cloudflare Pages, so Cloudflare handles the connection and can see the same things any host can: the address of the page requested and the IP address it was requested from. It does not see anything about your photos, for the same reason nothing else does.
Changes
If this page changes in a way that affects what leaves your browser, the date at the top changes and the change is described here. As of the date above, nothing derived from a photo has ever been transmitted, because the code to do so does not exist in this site.