Secure development
Most platform security is not your problem, and the parts that are yours are specific: the session token, the keystore, whatever secrets ship inside a build, and the honesty of the encryption claim you make on the listing.
Open Appsinity StudioYour session token
Studio authenticates with an email and password, or an OTP verification step, and holds a bearer token in local storage under appsinity_studio_token. Every Studio API call sends it as Authorization: Bearer <token>, and it is valid for thirty days.
- The token is the account. Anyone holding it can publish, unpublish and read your analytics.
- There is no two-factor option and no short-lived token mode, so the password is the only gate: pick one that is not used anywhere else.
- Sign out on shared machines. Logout clears the stored token; leaving a session open in a library browser is a standing credential.
- The API responses on a bad token are plain:
Sign in again firstandInvalid session. - Never paste a token into a support ticket or a developer chat; support never needs it.
Presigned uploads
File uploads never touch a platform secret. Studio asks the storage service for a presigned PUT for one object, then sends the bytes directly.
- The signed URL allows one object key for three hours. It cannot list a bucket or touch another path.
- Treat the URL as a short-lived secret: it is a write capability, and it should not be logged, pasted or cached.
- The client checks the size before requesting the URL and the storage service checks it again, so the second check is the one that matters.
- Never build a server that mints these URLs on behalf of players.
POST /api/storage/presign-upload
Authorization: Bearer <studio token>
{ "type": "game-build", "fileName": "mygame.zip",
"gameId": "<id>", "version": "1.4.0", "size": 734003200 }
200 {
"uploadUrl": "https://...", // PUT to this, expires in 10800s
"fileUrl": "https://storage.appsinity.com/public/games/...",
"objectKey": "games/<id>/builds/1.4.0/mygame.zip",
"contentType": "application/zip",
"expiresIn": 10800
}
PUT <uploadUrl> Content-Type: application/zip body: <bytes>Secrets in a web build
A web game is delivered as plain files into public storage. Everything in it is readable by everyone, and there is no way to hide it after upload.
| Never ship | Instead |
|---|---|
| API keys for any provider | A proxy endpoint you control |
| Database URLs or credentials | Server-side access only |
| Admin or owner tokens | Per-session tokens minted by your backend |
| Payment provider secret keys | Server-side order creation and verification |
| Source maps that reveal logic | Ship minified and drop the maps |
| Player lists or test accounts | Remove them before upload |
Keystore care
Android releases published through Appsinity are signed with a per-app keystore generated by the signing service: an RSA 2048 key, a certificate valid for ten thousand days, alias appsinity, and a subject carrying the app id under Appsinity Technologies, Faridabad, Haryana, IN. Keep the signing status on the build record honest.
- If you sign locally and upload, your own keystore is your responsibility; losing it means players cannot upgrade in place.
- Do not commit a keystore or its password into the repository you also export a web build from.
- Studio signing exists for convenience; a studio that plans long-lived version codes should decide deliberately which key signs its releases.
- Signing proves provenance, not safety. A signed build is not a vetted build, see Malware policy.
Licences and download tickets
Desktop installs run through short-lived licence tickets rather than a permanent device binding. The current model is deliberately small.
| Property | Value | Consequence |
|---|---|---|
| Devices per licence | 2 | A third install needs a release |
| Offline grace | 72 hours | A machine can run without contact for three days |
| Download ticket | Issued per request, single use | A copied ticket does not work |
| Enforcement | Client-side checks | Not a DRM boundary against a determined user |
Claims you make on the listing
The encryptedInTransit declaration is a security statement to players, and so is the privacy disclosure. Accuracy here is enforceable in a way that good intentions are not.
- Use HTTPS for every endpoint. A single plain HTTP call makes an encrypted-in-transit declaration false.
- Say what data leaves the device. In the disclosure, with named recipients.
- Publish a reachable support email. A security report that goes nowhere becomes a disclosed vulnerability.
- Rotate anything that leaked. Rotation is cheaper than an argument about whether it was exploited.
Frequently asked questions
Is there an API for my own CI pipeline?
There are no API keys and no service accounts. Studio's session token is the only credential, which is a deliberate reason not to automate against the publishing API.
Can I see security advisories or a bug bounty?
No programme is published. Report issues through [email protected] with the surface and a reproduction.
Does Appsinity scan my source?
Never. Scanning is over stored objects by extension and name, and it does not build or run your game.
My web build contains a key. What now?
Rotate the key immediately, remove it from the build, re-upload, then delete the old version from the listing. Assume it was read.
Developer publishing support: [email protected]
General support: [email protected]
Partnerships: [email protected]
APPSINITY