Secure Login
Every connection to your RSocial instance is secured with TLS encryption (the same technology used by banks and major websites). This ensures that any data transmitted between your browser and your RSocial device is encrypted in transit — protected from eavesdropping or man-in-the-middle attacks.
RSocial uses secure session management with signed tokens, automatic session expiration, and protection against common web attacks such as cross-site scripting (XSS) and cross-site request forgery (CSRF). Your login credentials are never stored in plain text — they are hashed using modern, salted hashing algorithms.
Read more — how your password is stored
When you create an account, RSocial never writes your actual password to disk. Instead it stores a hash of it. Hashing is a one-way process: it turns your password into a scrambled fingerprint that cannot be turned back into the original, no matter how much computing power you have. When you log in, RSocial hashes whatever you typed and compares the two fingerprints — it confirms you know the password without ever needing to know the password itself. Specifically, RSocial uses PBKDF2-HMAC-SHA256 with 100,000 iterations and a unique salt per account. The practical result: even in the unlikely event someone reached the account database, they would find only irreversible fingerprints, not a single readable password.
This is handled by the identity service's standard hashing pipeline, which stores each password as a self-describing record: a version marker, the per-account salt, the iteration count, and the resulting hash, all packed together. Because the format records its own parameters, the system can strengthen them over time — if the recommended iteration count rises, an account can be transparently re-hashed with the tougher settings the next time you log in, without you ever noticing. Two people who happen to choose the same password still get completely different stored hashes, because each has a unique salt, which defeats "rainbow table" attacks that rely on precomputing hashes of common passwords.
Read more — how your session is kept (and expires)
After you log in, RSocial doesn't keep asking for your password — it issues a signed token (a JWT, or JSON Web Token) that your browser presents with each request. Think of it like a tamper-evident wristband: it is signed with HMAC-SHA256, so your instance can instantly tell whether it's genuine, and any attempt to change what's written on it makes the signature invalid. These tokens are deliberately short-lived — an access token is good for only about fifteen minutes. Working quietly behind it is a longer-lived refresh token (valid for around seven days) that automatically gets you a fresh access token as you keep using the app. That refresh token rotates every time it is used — each use issues a new one and retires the old — and it can be revoked instantly on the server if anything looks wrong. So if a token were ever captured, its usefulness is measured in minutes, not months, and a stolen session can be cut off centrally.
If you've never seen inside a JWT: it's three parts separated by dots — a header, a payload, and a signature. The payload carries a handful of claims, such as who you are, your role, who issued the token, who it's meant for, and exactly when it expires. The signature is computed over the header and payload with HMAC-SHA256 using a secret only your instance knows, so changing even one character of the payload invalidates it. On every request the server re-checks all of that: the signature, the issuer, the intended audience, and the expiry time. The refresh token, by contrast, carries no claims at all — it's simply 64 bytes of cryptographic randomness recorded in the database, where it can be marked rotated or revoked. That split is deliberate: the thing you send constantly is short-lived and self-verifying, while the long-lived thing sits safely server-side where it can be switched off instantly.
Read more — how the connection is protected
RSocial is designed to run behind TLS, the same encryption that puts the padlock in your browser's address bar. TLS uses a certificate — a small file that both proves the server is really your instance and sets up an encrypted channel — so that everything travelling between your browser and your device is scrambled and can't be read or altered by anyone in between (this is what stops "eavesdropping" and "man-in-the-middle" attacks). You switch TLS on with a standard reverse proxy and a free certificate, for example from Let's Encrypt, and our deployment guide walks through it step by step.
The usual setup is a reverse proxy — typically nginx — sitting in front of your instance and handling the encrypted connection, then passing plain requests to the services behind it on your own machine. A tool like Certbot obtains a free certificate from Let's Encrypt and renews it automatically before it expires, so once it's configured you don't have to think about it again. It's worth being candid: TLS is not switched on by default, because in local development there's nothing to encrypt yet. Turning it on is the single most important step when you expose your instance to the internet, which is exactly why the deployment guide treats it as a required step rather than an optional extra.
Read more — resisting common web attacks (XSS & CSRF)
Two attacks are worth naming plainly. Cross-site scripting (XSS) is when someone tries to sneak malicious code into a page through something they typed — a comment, a name, a post. RSocial's interface treats everything a user types as plain text to be displayed, never as code to be run, so injected code simply appears as harmless characters. Cross-site request forgery (CSRF) tricks your browser into making a request you didn't intend, relying on login information the browser sends automatically. Because RSocial proves who you are with a token the app attaches deliberately — rather than an automatic cookie — this whole class of trick largely doesn't apply. On top of that, user-supplied content is carefully escaped before it's ever used in a database query, closing the door on injection attacks.
A little more detail on each. The interface is built with a modern framework that, by default, renders any value you type as text rather than markup — so a comment containing something that looks like code is shown literally, exactly as typed, instead of being executed. On the storage side, because posts and comments are written into the graph store with SPARQL, anything you type is escaped before it becomes part of a query, so it can't break out and change the query's meaning — the same principle that "parameterised queries" use to stop SQL injection. And because your identity rides in a bearer token that the app attaches on purpose, rather than a cookie the browser sends automatically to any matching site, the usual lever that CSRF attacks pull simply isn't there to pull.
Two-Factor Authentication
A strong password alone isn't enough in today's threat landscape. RSocial includes two-factor authentication (2FA) as a built-in feature, adding an extra layer of protection to your account.
With 2FA enabled, signing in requires both your password and a second verification step — typically a time-based code from an authenticator app on your phone. This means that even if someone somehow obtained your password, they still couldn't access your account without physical access to your second factor.
RSocial supports standard TOTP-based authenticator apps, so you can use the same tools you already trust for other accounts.
Read more — how TOTP actually works
The reason a second factor helps so much is that most account break-ins don't involve "cracking" anything. They happen because a password was reused on another site that got breached, guessed, or typed into a convincing fake login page. In every one of those cases the attacker ends up holding your password — and with two-factor authentication, that still isn't enough to get in.
Under the hood, RSocial uses TOTP, which stands for "time-based one-time password." It's an open standard supported by apps you may already use, such as Google Authenticator, Authy, and 1Password. Setting it up works like this: RSocial shows you a QR code once, which your app scans to learn a shared secret. From that moment on, your app and your instance can each independently produce the same short code — usually six digits — that changes roughly every 30 seconds. The clever part is that after that first setup, the secret never travels across the network again. Your phone calculates the current code entirely on its own, even in aeroplane mode, and RSocial calculates the same code on its side to compare. Because each code is valid for only about half a minute, a code that someone manages to glimpse or intercept is worthless almost immediately.
The mechanism itself is refreshingly simple. That "shared secret" is a random key, shown to your app as a QR code encoding a standard otpauth:// link. To produce a code, both sides take the current time, divide it into 30-second steps, and run an HMAC (a keyed hash) of that time-step using the shared secret; the result is truncated down to the six digits you see. Because it's driven by the clock rather than a counter, no communication is needed after setup — the two sides simply agree because they share the secret and roughly agree on the time. To stay forgiving of clocks that drift by a few seconds, your instance will accept a code from the immediately adjacent time-step as well, which is why a code entered right on the boundary still works.
Read more — recovery codes, so 2FA never locks you out
To make sure 2FA never locks you out, RSocial provides one-time recovery codes when you enable it. These are a short list of single-use backup codes you save somewhere safe in advance — a password manager, or printed and stored offline. If you ever lose your phone, you use one of them to get back in and set up a new authenticator. Each recovery code works only once, so a used code can't be replayed by anyone who later finds your list.
Role-Based Access Control
RSocial implements role-based access control (RBAC) to ensure that users only have access to the features and data they are authorized to use. Administrators can define roles and permissions at the community level, giving you granular control over who can do what within your space.
This means a regular member can interact with content without having access to administrative tools, and moderators can manage discussions without having access to system-level settings. Every action is scoped to the user's role, minimizing the risk of accidental or intentional misuse.
Read more — why it's enforced on the server, and "least privilege"
The most important thing about these permission checks is where they happen: on the server, not just in the interface. It's easy to hide a button from someone in the app, but hiding a button isn't security — a determined person can bypass the interface entirely and talk to the system directly. RSocial guards against this by checking permissions on the backend, for every protected action, on every request. An administrative action is gated by an authorization policy that the server enforces itself, so a restricted feature stays restricted even if someone goes around the interface completely. The interface hides options you can't use as a convenience; the server is what actually stops you from using them.
RSocial also follows a principle security professionals call least privilege: by default, an account is given the minimum access it needs to do ordinary things — post, comment, and take part — and nothing more. Elevated powers, like managing members or removing content, are granted deliberately to specific roles rather than being switched on for everyone. This keeps the blast radius of any single compromised account small: if an ordinary member's login were ever misused, it still couldn't reach the administrative controls, because that account was never handed those keys in the first place.
In practice, your role travels inside the signed login token described above, and each service checks it independently. On the identity side, sensitive endpoints are marked with an authorization policy — effectively "this action requires the admin role" — that the framework enforces before the code even runs. The content services do the same in their own way: a small guard inspects the role claim in your token and refuses anything that isn't allowed. Because the check reads the cryptographically signed token rather than trusting anything the browser says, there's no way to award yourself a role you weren't granted; the token would fail its signature check the moment it was altered.
Common Questions
If someone gets my password, are they in?
Not if you've enabled two-factor authentication. A password alone won't pass the second step, which needs the code from your phone. Turning on 2FA is the single biggest thing you can do to protect your account.
Do I stay logged in forever?
No — sessions expire on their own, and can be revoked. Your day-to-day access token lasts only minutes at a time and is refreshed quietly in the background while you're active.
Is my password ever visible to anyone?
No. It's turned into an irreversible fingerprint the moment you set it, and only that fingerprint is stored. Even someone with full access to the database could never read your actual password.