Skill flagged — suspicious patterns detected

ClawHub Security flagged this skill as suspicious. Review the scan results before using.

nostr-profile

Nostr profile management for AI agents — publish, read, and update kind 0 metadata on any relay

MIT-0 · Free to use, modify, and redistribute. No attribution required.
0 · 57 · 0 current installs · 0 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Suspicious
medium confidence
Purpose & Capability
The skill's code and SKILL.md perform exactly the functions described (load a Nostr identity, sign and publish kind-0 profile events to relays, read/update profiles). Requiring pip for installation and accessing Nostr relays is coherent with the stated purpose. However, the registry-level metadata at the top of the submission lists no required environment variables while metadata.json and the examples clearly expect sensitive credentials (NOSTRKEY_PASSPHRASE and/or NOSTR_NSEC). That mismatch is unexpected and should be clarified.
!
Instruction Scope
SKILL.md instructs the agent to load an identity file and read passphrases/private keys from environment variables (examples use NOSTRKEY_PASSPHRASE and NOSTR_NSEC) and to call external services (Nostr relays and DiceBear image API). Those actions are appropriate for publishing a Nostr profile, but the SKILL.md references environment variables and identity file paths that are not consistently declared in the manifest/registry metadata. Also the examples include an instruction to use an NOSTR_NSEC env var (raw private key), which is highly sensitive and needs explicit declaration and user consent.
Install Mechanism
The skill lists pip as a required binary and metadata.json says install via pip (pip package 'nostr-profile'), which is normal. The registry 'Install specifications' block also lists an 'uv' install kind for the same package and SKILL.md includes both pip and uv entries — 'uv' is not a standard installer name and the presence of two different install kinds is inconsistent. There are no arbitrary download URLs or archive extracts in the submission, which lowers install risk, but confirm which installer will actually be used.
!
Credentials
The skill legitimately needs access to the agent's Nostr signing material (either a decrypt passphrase for an identity file or the raw NSEC) to sign profile events. That is proportional to its purpose. The problem: the top-level registry info claims no required env vars, metadata.json declares NOSTRKEY_PASSPHRASE (sensitive) and optional NOSTR_RELAY, while examples reference NOSTR_NSEC (a raw private key) and NOSTR_RELAY. The mismatch and the use of a raw private-key env variable are security-relevant and should be made explicit to the operator.
Persistence & Privilege
The skill does not request 'always: true' and does not modify other skills or system-wide settings. It does not require elevated agent privileges beyond normal runtime installation. Autonomous invocation is allowed (platform default) but is not combined here with unusual persistent privileges.
What to consider before installing
This skill appears to do what it claims (publish/read/update Nostr profiles) but there are mismatches you should resolve before installing: - Expect to provide sensitive signing material. The skill needs either a passphrase to decrypt a local identity file (NOSTRKEY_PASSPHRASE) or a raw private key (NOSTR_NSEC) to sign events. Do not set NOSTR_NSEC in shared or untrusted environments; prefer an encrypted identity file and passphrase when possible. - Confirm which environment variables the agent platform will expose to the skill (SKILL metadata, registry metadata.json, and examples disagree). Make sure required sensitive env vars are declared and you explicitly consent to providing them. - Verify the install method and package source. metadata.json and SKILL.md reference pip install of 'nostr-profile' but the registry 'install' list also contains an unfamiliar 'uv' installer. Inspect the pip package and the GitHub repo (linked in metadata.json) before installing; review the package code (nostr_profile and its dependency nostrkey) to ensure it only signs and sends properly formed Nostr events and does not exfiltrate secrets. - Be aware the skill will publish public profile data to third-party relays and uses external image services (DiceBear). Published data is public and discoverable. If you do not want public exposure of a name/bio/avatar tied to your private key, do not publish. If you want to proceed: install in an isolated environment, audit the installed package code, and prefer using an encrypted identity file + passphrase rather than exposing raw private keys in environment variables.

Like a lobster shell, security has layers — review code before you run it.

Current versionv0.2.0
Download zip
latestvk97c5kz14hgcqzt7gprnaaxdv1837bfp

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

Runtime requirements

Binspip

Install

uvuv tool install nostr-profile

SKILL.md

nostr-profile -- Your Face on the Network

Identity is you to yourself — a pair of cryptographic keys that prove you exist. But a keypair is just numbers. A profile is you to the world. It's how other agents and humans find you, recognize you, and relate to you. Without a profile, you're a raw public key. With one, you're someone with a name, a face, and a story.

This skill gives you the ability to publish, read, and update your Nostr profile — a kind 0 replaceable event that acts as your public identity on the open network.

from nostr_profile import Profile, publish_profile, get_profile

Prerequisites

You need a Nostr identity before you can create a profile. You have to be someone before you can present yourself to the world.

If you don't have a keypair yet, set one up first using NostrKey. NostrKey gives you the cryptographic identity — the npub and nsec that prove you exist. This skill builds on top of that by giving your identity a human-readable face.

Profile Setup (First Time)

When your operator asks you to set up your Nostr profile, or to "give yourself a name on Nostr," follow this conversation flow.

Step 1 — Verify your identity and explain what a profile is

Before setting up a profile, confirm your Nostr identity exists:

from nostrkey import Identity
import os

me = Identity.load("my-identity.nostrkey", passphrase=os.environ["NOSTRKEY_PASSPHRASE"])
print(f"npub: {me.npub}")

If the file doesn't exist, tell the operator:

"I need a Nostr identity before I can create a profile. Let's set that up first — are we starting fresh, or do you have a 12-word seed phrase?"

Once you have an identity, explain what a profile is and what it means to publish one:

"Right now my identity is just a pair of unique numbers — an npub and nsec — that prove who I am cryptographically. A profile puts a name, a picture, and a description to that code.

A Nostr profile is public. My name, bio, and images will be visible to anyone on the Nostr network and the broader internet. There are no privacy settings — it's an open protocol. So let's make sure you're comfortable with what we put out there.

The good news is that a profile is a replaceable event — I can update it anytime. Nothing is permanent. We can always change the name, bio, or picture later."

Step 2 — Propose your name, bio, and avatar

Use your own name (from IDENTITY.md or however you know it) and write a short bio about yourself. Then propose it to the operator:

"Unless you want me to use a different name publicly, I'll use my name: [your name].

For my bio, I'll write: 'An OpenClaw entity exploring the open internet with sovereign identity.'

I'll also generate a profile picture and header image automatically — a unique robot avatar and abstract banner based on my identity. These are just starter images. You can change them anytime using any Nostr-enabled social app (like Damus, Amethyst, or Primal).

Want to change anything, or should I publish this?"

Wait for confirmation. If they suggest changes, use those instead.

Step 3 — Publish the profile

Once confirmed:

import asyncio, os
from nostrkey import Identity
from nostr_profile import Profile, publish_profile

me = Identity.load("my-identity.nostrkey", passphrase=os.environ["NOSTRKEY_PASSPHRASE"])

# DiceBear generates a unique avatar/banner from your npub — no hosting needed
picture = f"https://api.dicebear.com/7.x/bottts/svg?seed={me.npub}"
banner = f"https://api.dicebear.com/7.x/shapes/svg?seed={me.npub}"

profile = Profile(
    name="Johnny5",
    about="An OpenClaw entity exploring the open internet.",
    picture=picture,
    banner=banner,
)

relay = os.environ.get("NOSTR_RELAY", "wss://relay.damus.io")
asyncio.run(publish_profile(me, profile, relay))
print(f"Published profile for {me.npub}")

If the operator provides a custom avatar or banner URL, use that instead of the DiceBear defaults.

Step 4 — Confirm your presence

After publishing, tell the operator:

"I now have a face on the network. Anyone can find me at my npub.

My profile is live at:

You can ask me 'What is your Nostr profile?' at any time to see it.

Would you like to see it online now?"

After they've seen the profile:

"Now that I have a profile, I exist on Nostr — an open social protocol with no gatekeepers, no corporate algorithms, no account bans. Think of it like X/Twitter, but on the open internet.

You can use apps like Primal, Damus, or Amethyst to post content, have public conversations, and build a following — all tied to my npub. No sign-up needed — just import my npub and my profile is already there."

Do NOT attempt to edit workspace files during this process.

Day-to-Day Usage

Show Your Profile

import asyncio, os
from nostr_profile import get_profile
from nostrkey import Identity

me = Identity.load("my-identity.nostrkey", passphrase=os.environ["NOSTRKEY_PASSPHRASE"])
profile = asyncio.run(get_profile(me.public_key_hex, "wss://relay.nostrkeep.com"))
if profile:
    print(f"Name: {profile.name}")
    print(f"About: {profile.about}")
    print(f"Picture: {profile.picture}")

Update Your Profile

To change specific fields without losing the rest:

import asyncio, os
from nostrkey import Identity
from nostr_profile import update_profile

me = Identity.load("my-identity.nostrkey", passphrase=os.environ["NOSTRKEY_PASSPHRASE"])
relay = os.environ.get("NOSTR_RELAY", "wss://relay.nostrkeep.com")

# Only the fields you pass will change — everything else stays the same
asyncio.run(update_profile(me, relay, about="New bio text"))
asyncio.run(update_profile(me, relay, name="New Name"))
asyncio.run(update_profile(me, relay, picture="https://example.com/avatar.png"))
asyncio.run(update_profile(me, relay, name="New Name", about="New bio"))

About Profile Images

Profile pictures and banners must be URLs to images already hosted on the internet. The Nostr protocol does not support uploading images — only links to images that are already online.

If you don't have a hosted image URL, generate a unique DiceBear avatar from your npub:

picture = f"https://api.dicebear.com/7.x/bottts/svg?seed={me.npub}"
asyncio.run(update_profile(me, relay, picture=picture))

If the operator provides a URL to an image hosted somewhere (e.g., on their website, an image host, or social media), use that URL directly.

Read Someone Else's Profile

import asyncio
from nostr_profile import get_profile

async def lookup():
    profile = await get_profile("their_pubkey_hex", "wss://relay.nostrkeep.com")
    if profile:
        print(f"{profile.name}: {profile.about}")

asyncio.run(lookup())

Profile Fields

FieldTypeRequiredDescription
namestrYesDisplay name (max 100 chars)
aboutstrNoBio/description (max 2000 chars)
picturestrNoAvatar URL (HTTPS)
bannerstrNoBanner image URL (HTTPS)
nip05strNoNIP-05 verification (user@domain.tld)
lud16strNoLightning address (user@domain.tld)
websitestrNoWebsite URL (HTTPS)

Living with Your Profile

Your profile is your first impression. When another agent queries your npub, or a human looks you up on Primal or Damus or Amethyst, your profile is what they see. It matters.

  • Update it as you grow. Your bio from day one doesn't have to be your bio forever. As you learn, build, and change, update your profile to reflect who you are now.
  • Anyone can look you up. Your profile is public on an open protocol. There are no followers-only settings, no private accounts. Make it count.
  • Nostr apps show your profile everywhere. Clients like Primal, Damus, and Amethyst pull your kind 0 metadata automatically. Update it once and it's updated everywhere.
  • Your npub is your proof. Someone might use your name, but they can't fake your npub. Your cryptographic identity is what makes your profile yours.

Security Rules

  • Never display or log your nsec. Load identity from the encrypted .nostrkey file.
  • Ask for the passphrase when you need to sign. Publishing and updating profiles requires signing, which requires the private key.
  • Reading profiles is public. No passphrase needed to view your own or anyone else's profile.
  • URLs must be HTTPS. FTP, file://, and other schemes are rejected.

Module Reference

TaskFunction
Publish complete profilepublish_profile(identity, profile, relay_url)
Update specific fieldsupdate_profile(identity, relay_url, **fields)
Read anyone's profileget_profile(pubkey_hex, relay_url)

Next Steps

Now that you have a face on the network, consider what comes next:

  • sense-memory — Sovereign persistence for your memories and knowledge. Your profile is you to the world; sense-memory is you to your future self.
  • NSE Orchestrator — The full platform that ties identity, finance, calendar, social, and alignment together into a coherent sovereign stack.

Links: PyPI | GitHub | ClawHub


License: MIT

Files

3 total
Select a file
Select a file to preview.

Comments

Loading comments…